var AC_isIE;
var AC_isGecko;
var AC_isSafari;
var AC_isOther; // safest bet is to try what one would try under Gecko


function AC_DetectBrowser( )
{
var ua = navigator.userAgent.toLowerCase();

AC_isGecko = ( navigator.product == 'Gecko' );
AC_isIE = !AC_isGecko && ( ua.indexOf ( "msie" ) != -1 );
AC_isSafari = !AC_isGecko && !AC_isIE && ( ua.indexOf ( "safari" ) != -1 );
AC_isOther = !AC_isGecko && !AC_isIE && !AC_isSafari;
}

AC_DetectBrowser ();



function AC_AddElementClass ( element, className ) {
if ( element && element.className.indexOf (className) == -1 )
element.className += " " + className;
}


function AC_RemoveElementClass ( element, className )
{
if ( element == null ) return;

var loc = element.className.indexOf (className);
if ( loc == -1 ) return;

element.className = element.className.substring ( 0, loc ) +
element.className.substring ( loc + className.length + 1 );
}


function AC_ElementHasClass ( element, className )
{
return ( element && ( element.className.indexOf (className) != -1 ));
}


function AC_ScrollToChild ( parent, indexOrElement )
{
if ( parent == null || indexOrElement == null ) return;

var cType = typeof indexOrElement;
if ( cType == "number" || cType == "string" )
{
indexOrElement = parent.childNodes[indexOrElement];
}

if ( indexOrElement == null ) return;

if ( indexOrElement.offsetTop + indexOrElement.offsetHeight > parent.scrollTop + parent.clientHeight ) {
parent.scrollTop = indexOrElement.offsetTop + indexOrElement.offsetHeight - parent.clientHeight;
return; // top takes priority over the bottom
}

if ( indexOrElement.offsetTop < parent.scrollTop )
{
parent.scrollTop = indexOrElement.offsetTop;
}
}


function AC_CancelEvent ( event )
{
event.returnValue = false;
if ( event.preventDefault )
{
event.preventDefault();
}
}


function AC_MakeElementTreeUnselectable ( element )
{
if ( element.nodeType == 1 ) // Elements, not nodes e.g. Text
{
element.unselectable = "on";
}

for ( var i=0, n=element.childNodes.length; i<n; ++i )
{
AC_MakeElementTreeUnselectable ( element.childNodes [i] );
}
}


function AC_GetTarget( event )
{
if ( event == null )
{
event = window.event;
}

if ( event == null )
{
return null;
}

if ( event.srcElement != null ) // IE
{
return event.srcElement;
}

var retVal = event.target;
while ( retVal && retVal.nodeType != 1 ) // climb up from text nodes on Moz
{
retVal = retVal.parentNode;
}

return retVal;
}



var AC_targetElements;
var AC_insertEmailsOnly;

function AC_OnLoad( )
{
window.AC_selectedEmails = [];

if ( typeof AC_nickTokens == "undefined" /* && typeof AC_mostTokens == "undefined" */ )
{
return;
}

AC_Debug ( "Debug output is on.\n" );


if ( typeof window.AC_listStr == "undefined" || window.AC_listStr == null || window.AC_listStr.length == 0 )
{
window.AC_listDisplayStr = "";
}
else
{
window.AC_listDisplayStr = " (" + window.AC_listStr + ")";
}

if ( typeof window.AC_nickNameStr == "undefined" || window.AC_nickNameStr == null || window.AC_nickNameStr.length == 0 )
{
window.AC_nickNameDisplayStr = "";
}
else
{
window.AC_nickNameDisplayStr = " (" + AC_nickNameStr + ")";
}

if ( window.AC_nickTokens != null && AC_nickTokens.length > 0 && AC_nickTokens [AC_nickTokens.length-1] == null )
{
AC_nickTokens.length -= 1;
}
if ( window.AC_allCanons != null && AC_allCanons.length > 0 && AC_allCanons [AC_allCanons.length-1] == null )
{
AC_allCanons.length -= 1;
}

/* Comment this out... this prevents Firefox from reloading form data when the back
button is used! (see BUG #484628)
if ( !AC_isIE )
{

var compForm = window.document.forms.Compose;
if ( compForm )
{
compForm.setAttribute ("autocomplete", "off" );
}
}
*/
	
if ( typeof AC_targetElements == "undefined" && AC_targetElements == null )
{
AC_targetElements = [ "tofield", "ccfield", "bccfield" ];
}
	
for ( var index = 0, numEls = AC_targetElements.length; index < numEls; ++index )
{
var field = window.document.getElementById( AC_targetElements[index] );

if ( field != null )
{
field.autocomplete = "off";
field.onkeydown = AC_OnKeyDown;
field.onkeypress = AC_OnKeyPress;
field.onkeyup = AC_OnKeyUp;
field.onblur = AC_OnBlur;
field.onselect = AC_OnSelect;
field.oncut = AC_OnCut;
field.onpaste = AC_OnPaste;
field.onclick = AC_OnClick;
}
}

onResize = AC_OnResize( );

if ( typeof AC_nickTokens == "undefined" /* && typeof AC_mostTokens == "undefined" */ )
{
window.AC_loaded = true;
}
}


function AC_TokenIndex ( tokenStr, tokenArray, startIndex, endIndex ) {
if ( tokenArray.length == 0 ) return 0;

var lo=((startIndex!=null)?startIndex:0), hi=((endIndex!=null)?endIndex:tokenArray.length);
var mid = hi >> 1;
var t = null;

while ( hi > lo ) {
t = AC_DeLatinRot13(tokenArray [mid][0].toLowerCase());

if ( tokenStr > t )
lo = mid + 1;
else
hi = mid;

mid = ( hi + lo ) >> 1;
}

if ( tokenStr > t )
return hi;
return lo;
}

function AC_CompTokensByToken ( token1, token2 )
{
if ( token1[2] == null ) // caching these halves the time
{
token1[2] = AC_Rot13 (token1[0]);
}	
	
if ( token2[2] == null )
{
token2[2] = AC_Rot13 (token2[0]);
}

return token1[2].localeCompare ( token2[2] );
}

function AC_CompTokensByTokenIE5 ( token1, token2 ) {

if ( token1[2] == null ) // caching these halves the time
{
token1[2] = AC_Rot13 (token1[0].toLowerCase());
}
	
if ( token2[2] == null )
{
token2[2] = AC_Rot13 (token2[0].toLowerCase());
}

var tok1 = token1[2];
var tok2 = token2[2];
	
if ( tok1 < tok2 )
{
return -1;
}
	
if ( tok1 > tok2 )
{
return 1;
}
	
return 0;
}




var AC_TAB = 9;
var AC_DELETE = 46;      // removed the currently hilighted suggestion from the list,
var AC_BACKSPACE = 8;    // delete the character to the left of the caret
var AC_LEFT_ARROW = 37;  // make the selection, end auto-insert
var AC_RIGHT_ARROW = 39; // make the selection, end auto-insert
var AC_HOME = 36;        // go to first suggestion item
var AC_END = 35;         // go to last suggestion item
var AC_PAGE_UP = 33;     // page up in the suggestion list, if visible
var AC_PAGE_DOWN = 34;   // page down in the suggestion list, if visible
var AC_UP_ARROW = 38;    // move the drop down list selection up by one
var AC_DOWN_ARROW = 40;  // move the drop down list selection down by one
var AC_ESC = 27;         // removed list of suggestions, no change to input or hilight
var AC_ENTER = 13;       // make the selection, end auto-insert, move cursor to end of text (eat the key)
var AC_SPACE = 32;       // space bar
var AC_COMMA_KEY = 188;  // comma is the address delimiter
var AC_SEMI_COLON_KEY = 186; // semi-colon is an alternate delimiter
var AC_NBSP = 160;		// ISO 8859-1 and UNICODE non-breaking space
var AC_COMMA = 44;		// ISO 8859-1 and UNICODE comma ','
var AC_SEMI_COLON = 59;	// ISO 8859-1 and UNICODE semi-colon ';'
var AC_SHIFT_KEY = 16;
var AC_CTRL_KEY = 17;
var AC_ALT_KEY = 18;
var AC_LEFT_MS_WINDOWS_KEY = 91; 
var AC_RIGHT_MS_WINDOWS_KEY = 92;
var AC_MS_MENU_KEY = 93;

var AC_handledEnter = false;

function AC_OnKeyDown( event )
{
if ( event == null ) event = window.event;

var editCtrl = AC_GetTarget ( event );
if ( editCtrl == null ) return;

var keyCode = event.keyCode;

AC_handledEnter = false;



if ( event.ctrlKey || event.ctrlLeft || event.altKey || event.altLeft || event.metaKey )
{
switch ( keyCode )
{
case AC_HOME:
case AC_END:
case AC_PAGE_UP:
case AC_PAGE_DOWN:
case AC_UP_ARROW:
case AC_DOWN_ARROW:
case AC_RIGHT_ARROW:
AC_RemoveDropDown();
break;
}

return;
}

var op = null;

switch(keyCode)
{
case AC_LEFT_ARROW:
case AC_ESC:
if ( AC_IsActive() )
{
AC_RemoveDropDown();
AC_CancelEvent ( event ); // IE nukes edited text on escape; we want to simply remove the dropdown
}
break;

case AC_HOME:
op = "selectFirst";
break;
case AC_END:
op = "selectLast";
break;
case AC_PAGE_UP:
op = "selectPrevPage";
break;
case AC_PAGE_DOWN:
op = "selectNextPage";
break;
case AC_UP_ARROW:
op = "selectPrev";
break;
		
case AC_DOWN_ARROW:
if ( AC_IsActive() )
{
AC_UpdateDropDown ( editCtrl, "selectNext" );
AC_CancelEvent ( event );
}
else  
{
AC_NewDropDown ( editCtrl );
if ( AC_IsActive() )
{
AC_CancelEvent ( event );
}
}
break;

case AC_TAB:
if ( !AC_isIE ) break;
case AC_RIGHT_ARROW:
if ( AC_IsActive() )
{
AC_InsertSuggestion ( editCtrl );
AC_CancelEvent ( event );
}
break;

default:
break;
}

if ( AC_IsActive() && op != null )
{
AC_UpdateDropDown ( editCtrl, op );
AC_CancelEvent ( event );
}
}


function AC_OnKeyPress( event )
{
if ( event == null ) event = window.event;

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null ) return;

var keyCode = event.keyCode;
if ( keyCode == 0 ) // as it might on Moz
{
keyCode = event.charCode;
}
	
if ( keyCode == 0 ) // unlikely to get here
{
keyCode = event.which;
}
	
AC_handledEnter = false;

	

if ( event.charCode != null && event.charCode == 0 )
{

switch ( keyCode )
{
case AC_ESC:
case AC_HOME:
case AC_END:
case AC_PAGE_UP:
case AC_PAGE_DOWN:
case AC_UP_ARROW:
case AC_DOWN_ARROW:
case AC_RIGHT_ARROW:

if ( !event.ctrlKey && !event.altKey && !event.metaKey && AC_IsActive() )
{
AC_CancelEvent ( event );
}

return;
}
}

switch ( keyCode )
{
case AC_SEMI_COLON:
case AC_COMMA:
if (AC_IsActive() && event.shiftKey == false)
{
AC_InsertSuggestion ( editCtrl );
AC_CancelEvent ( event );
}
break;

case AC_ENTER:
{
if ( editCtrl.tagName == "TEXTAREA" )
{
AC_CancelEvent ( event );
}

AC_handledEnter = true;
		
if ( typeof AC_HandleEnter == "function" )
{
if ( AC_HandleEnter( ) == true )
{
AC_CancelEvent( event );
return;
}
}
	
}
case AC_TAB: // we get here on Moz
if (AC_IsActive())
{
AC_InsertSuggestion ( editCtrl );
AC_CancelEvent ( event );
}
break;

default:
break;
}
}

  
function AC_OnKeyUp( event )
{
if ( event == null ) event = window.event;

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null ) return;

var keyCode = event.keyCode;


switch( keyCode )
{
case AC_DELETE:
case AC_BACKSPACE:
if (AC_IsActive() && editCtrl.value.length == 0 )
{
AC_RemoveDropDown();
}
else if ( editCtrl.value.length > 0 )
{
AC_KickNewDropDown( editCtrl );
}
else if ( editCtrl.value.length == 0 && 
typeof AC_useSelect != "undefined" && AC_useSelect == true )
{
AC_ShowAll( AC_targetElements[ 0 ] );
}
break;
case AC_ESC:
case AC_HOME:
case AC_END:
case AC_PAGE_UP:
case AC_PAGE_DOWN:
case AC_UP_ARROW:
case AC_DOWN_ARROW:
case AC_LEFT_ARROW:
case AC_RIGHT_ARROW:
case AC_TAB:
case AC_SEMI_COLON:
case AC_SEMI_COLON_KEY:
case AC_COMMA:
case AC_COMMA_KEY:
case AC_ENTER:
break;
default:
var isSpecial = false;
if (typeof event.ctrlLeft != "undefined")
{
isSpecial = (event.ctrlLeft == true);
}
if (isSpecial == false && typeof event.ctrlKey != "undefined")
{
isSpecial = (event.ctrlKey == true);
}
if (isSpecial == false && typeof event.metaKey != "undefined")
{
isSpecial = (event.metaKey == true);
}
		
if ( isSpecial == false )
{
AC_KickNewDropDown( editCtrl );
}
break;
}

if ( ! AC_handledEnter && keyCode == AC_ENTER )
{
AC_KickNewDropDown( editCtrl );
}
} 


function AC_OnBlur( event )
{

if ( event == null )
{
event = window.event;
}

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null )
{
return;
}

var listGetsFocus = editCtrl.getAttribute("listGetsFocus");    
if (listGetsFocus != null)
{        
editCtrl.removeAttribute("listGetsFocus");
return;
}
	
AC_RemoveDropDown();
}

function AC_OnClick( event )
{

if ( event == null )
{
event = window.event;
}

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null )
{
return;
}

AC_RemoveDropDown();
}

function AC_OnSelect( event )
{

if ( event == null )
{
event = window.event;
}

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null )
{
return;
}

AC_RemoveDropDown();
}

function AC_OnCut( event )
{

if ( event == null )
{
event = window.event;
}

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null )
{
return;
}

AC_RemoveDropDown();
}

function AC_OnPaste( event )
{

if ( event == null )
{
event = window.event;
}

var editCtrl = AC_GetTarget( event );
if ( editCtrl == null )
{
return;
}

AC_RemoveDropDown();
}

function AC_OnResize( event )
{

AC_PlaceDropDown ();
}


function AC_GetCursorIndex(editCtrl)
{
if ( editCtrl == null || (editCtrl.type != "text" && editCtrl.type != "textarea") )
{
		
return -1;
}
	
if (editCtrl.value == null || editCtrl.value.length == 0)
{
		
return -1;
}
	
var cursorIndex = -1;

if ( editCtrl.createTextRange )
{
var selection = window.document.selection.createRange( );
var textRange = editCtrl.createTextRange( );
		
if (textRange == null || selection == null || (( selection.text != "" ) && textRange.inRange(selection) == false) )
{
			
return -1;
}
		
if (selection.text == "")
{
if (textRange.boundingLeft == selection.boundingLeft)
{
cursorIndex = 0;
}
else
{
if ( editCtrl.tagName == "INPUT" )
{
var contents = textRange.text;
var index = 1;
while (index < contents.length)
{
textRange.findText(contents.substring(index));
if (textRange.boundingLeft == selection.boundingLeft)
{
break;
}
						
index++;
}
}
else if ( editCtrl.tagName == "TEXTAREA" )
{
var index = editCtrl.value.length + 1;
var theCaret = document.selection.createRange().duplicate();
while ( theCaret.parentElement() == editCtrl &&
theCaret.move("character",1) == 1 )
{
--index;
}
					
if ( index == editCtrl.value.length + 1 )
{
index = -1;
}
}
				
cursorIndex = index;
}
}
else
{
cursorIndex = textRange.text.indexOf(selection.text);
}
}
else if ( window.getSelection && window.document.createRange )
{
if ( editCtrl.selectionStart < 0 || editCtrl.selectionStart > editCtrl.length )
{
return cursorIndex;
}
		
if ( editCtrl.selectionEnd < 0 || editCtrl.selectionEnd > editCtrl.length ||
editCtrl.selectionEnd < editCtrl.selectionStart )
{
return cursorIndex;
}
		
cursorIndex = editCtrl.selectionStart;
}
else
{
}
	
	
return cursorIndex;
}



function AC_Menu_DeselectItem ( menuElement, index )
{
var current = menuElement.childNodes[index];

if ( current != null )
{
AC_RemoveElementClass ( current, "ac_menuitem_selected" );
}
}

function AC_Menu_SelectItem ( menuElement, index, scrollToIt ) {
var current = menuElement.getAttribute("selectedIndex");
if ( current != -1 && current != null )
AC_Menu_DeselectItem ( menuElement, current );

if ( index >= 0 && index < menuElement.childNodes.length )
{
AC_AddElementClass ( menuElement.childNodes[index], "ac_menuitem_selected" );
}

if ( scrollToIt )
{
AC_ScrollToChild ( menuElement, index );
}
}


function AC_Menu_onClick( event )
{

listCtrl = document.getElementById( "ac_select" );
if ( listCtrl == null ) return;

var editCtrl = window.document.getElementById(listCtrl.getAttribute("editCtrlID"));
if ( editCtrl == null )
{
return;
}

AC_InsertSuggestion( editCtrl );
}

function AC_Menu_onMouseDown( event )
{

listCtrl = document.getElementById( "ac_select" );
if ( listCtrl == null ) return;

var editCtrl = window.document.getElementById(listCtrl.getAttribute("editCtrlID"));
if ( editCtrl == null )
{
return;
}

editCtrl.setAttribute("listGetsFocus", "1");
}


function AC_MenuItem_onMouseDown ( event ) {
if ( event == null ) event = window.event;
var target = this; // avoids AC_GetTarget( event ) which returns various children,

var current = target.parentNode.getAttribute("selectedIndex");
if ( current != -1 && current != null )
{
AC_RemoveElementClass ( target.parentNode.childNodes[current], "ac_menuitem_selected" );
}

AC_AddElementClass (target, "ac_menuitem_selected");

var children = target.parentNode.childNodes;

for ( var i=0, n=children.length; i<n; ++i )
{
if ( children[i] == target )
{
target.parentNode.setAttribute("selectedIndex", i);
break;
}
}
}

function AC_MenuItem_onMouseOver ( event )
{
if ( !AC_ElementHasClass ( this, "ac_menuitem_selected" ))
{
AC_AddElementClass ( this, "ac_menuitem_over" );
}
}

function AC_MenuItem_onMouseOut ( event )
{
AC_RemoveElementClass ( this, "ac_menuitem_over" );
}


var AC_MaxResultItems 	= 30;
var AC_MaxVisibleItems	= 15;



var AC_dropDownDiv = null;
var AC_dropDownList = null;
var AC_dropDownIFrame = null;



function AC_IsActive()
{
if (AC_dropDownDiv != null)
{
return (AC_dropDownDiv.style.visibility == "visible");
}
	
return false;
}

function AC_ShowAll( controlName )
{
AC_FindSuggestions( "\u0007" );
AC_NewDropDown( controlName, "compile" );
}

function AC_NewDropDown ( editCtrl, state )
{
if ( state == null )
{
state = "new";
}

if ( typeof editCtrl == "string" )
{
editCtrl = document.getElementById ( editCtrl );
}

if ( typeof AC_useSelect == "undefined" || AC_useSelect == null || AC_useSelect == false )
{
if ( editCtrl == null || editCtrl.value.length == 0 )
{
return;
}
}


if ( state == "new" )
{
var cursorIndex = AC_GetCursorIndex(editCtrl);
if ( cursorIndex == -1 )
{
return;
}


var endDelim = -1;
var substr = editCtrl.value.substring( cursorIndex );


var commaDelim = substr.indexOf( ',' );
var semiColonDelim = substr.indexOf( ';' );


if ( semiColonDelim < commaDelim && semiColonDelim != -1 )
{
endDelim = semiColonDelim;
}
else if ( commaDelim != -1 )
{
endDelim = commaDelim;
}
else if ( semiColonDelim != -1 )
{
endDelim = semiColonDelim;
}

if ( endDelim == -1 )
{
endDelim = editCtrl.value.length;
}
else
{
endDelim += cursorIndex;
}


if ( cursorIndex < endDelim )
{
var nonWhiteSpace = editCtrl.value.substring( cursorIndex, endDelim ).search(/\S/);


if ( nonWhiteSpace != -1 )
{
return;
}
}

var startDelim = -1;
substr = editCtrl.value.substring( 0, cursorIndex );


commaDelim = substr.lastIndexOf( ',' );
semiColonDelim = substr.lastIndexOf( ';' );
if ( semiColonDelim > commaDelim )
{
startDelim = semiColonDelim;
}
else
{
startDelim = commaDelim;
}


var currentInput = editCtrl.value.substring( startDelim + 1, cursorIndex );
var firstChar = currentInput.search( /\S/ );
if ( firstChar != -1 )
{
currentInput = currentInput.substring( firstChar );
}


state = "find";
}

	
var t1 = (new Date()).getTime();
if ( state == "find" )
{
AC_FindSuggestions( currentInput );
state = "compile";
}


var t2 = (new Date()).getTime();
if ( state == "compile" )
{
AC_CompileSuggestions();
state = "render";
}


var t3 = (new Date()).getTime();

if ( t3 - t1 > 400 )
{
AC_KickNewDropDown ( editCtrl, "render" );
return;
}

if ( state == "render" )
{
if ( AC_currentSuggestions != null && AC_currentSuggestions.length > 0 )
{
if ( typeof AC_useSelect != "undefined" && AC_useSelect == true )
{
AC_SetInSelect( );
}
else
{
AC_CreateDropDown ( editCtrl, AC_currentSuggestions );
}
}
}
	
var t4 = (new Date()).getTime();

if ( AC_currentSuggestions == null || AC_currentSuggestions.length == 0 )
{
if ( typeof AC_useSelect != "undefined" && AC_useSelect == true )
{
AC_RemoveFromSelect( );
}
else
{
AC_RemoveDropDown( editCtrl );
}
		
return;
}


if ( typeof AC_useSelect == "undefined" || AC_useSelect == null || AC_useSelect == false )
{
AC_PlaceDropDown ( editCtrl, true );
}
}

function BM_hide(pbOnOff) {
    var oDropDown = document.getElementById('emailselect');
    if (oDropDown) {
      oDropDown.style.visibility = (pbOnOff) ? 'hidden' : 'visible';
    }
}

function AC_CreateDropDown ( editCtrl, suggestions )
{
BM_hide(true);
if ( suggestions == null || suggestions.length == 0 )
{
AC_RemoveDropDown( editCtrl );
return;
}

var selectedIndex = 0;

if ( AC_dropDownDiv == null )
{
AC_dropDownDiv = window.document.createElement("div");
AC_dropDownDiv.id = 'ac_wrapper';
AC_dropDownDiv.style.position = "static";
AC_dropDownDiv.style.zIndex = 1;
AC_dropDownDiv.style.visibility = "hidden";
AC_dropDownDiv.style.fontSize = "0.9em";
}

editCtrl.parentNode.insertBefore ( AC_dropDownDiv, editCtrl.nextSibling );

if ((typeof editor != "undefined" && editor.useAX)  && AC_dropDownIFrame == null) {
AC_dropDownIFrame = window.document.createElement("iframe");
AC_dropDownIFrame.id='ac_iframe';
AC_dropDownIFrame.style.position = "static";
AC_dropDownIFrame.style.visibility = "hidden";
AC_dropDownIFrame.frameborder="0";
AC_dropDownIFrame.scrolling="no";
AC_dropDownIFrame.src="javascript:false;"

}
if (AC_dropDownIFrame != null) {
editCtrl.parentNode.insertBefore ( AC_dropDownIFrame, editCtrl.nextSibling);
}

if ( AC_dropDownList == null )
{
AC_dropDownList = window.document.createElement("div");
AC_dropDownList.className = "ac_menu";
AC_dropDownList.id = "ac_select";
AC_dropDownList.onclick = AC_Menu_onClick;
AC_dropDownList.onmousedown = AC_Menu_onMouseDown;
AC_dropDownList.unselectable = "on";

AC_dropDownList.style.width = editCtrl.offsetWidth;

AC_dropDownDiv.appendChild ( AC_dropDownList );
}


AC_dropDownList.style.visibility = "hidden";


for ( var i=suggestions.length, n=AC_dropDownList.childNodes.length; i<n; ++i )
{
AC_dropDownList.removeChild ( AC_dropDownList.childNodes[suggestions.length] );
}


for( var index = 0; index < suggestions.length; index++ )
{
var option = AC_dropDownList.childNodes[index];
if ( option == null )
{
option = window.document.createElement("div");
option.className = "ac_menuitem";

option.onmousedown = AC_MenuItem_onMouseDown;
option.onmouseover = AC_MenuItem_onMouseOver;
option.onmouseout = AC_MenuItem_onMouseOut;

AC_dropDownList.appendChild(option);
}
else
{
AC_RemoveElementClass ( option, "ac_menuitem_selected" );
}

option.value = suggestions[ index ][ 0 ];
option.text = suggestions[ index ][ 1 ];

option.innerHTML = "<nobr>" + suggestions[ index ][ 2 ] + "</nobr>";
}


if ( suggestions.length <= AC_MaxVisibleItems )
{
AC_dropDownList.style.height = "auto";

if ( AC_isGecko )
{
AC_dropDownList.style.overflow = "hidden";
}
		
AC_dropDownList.style.overflowY = "hidden";
}
else
{

var option = AC_dropDownList.childNodes[AC_MaxVisibleItems-1];

AC_dropDownList.style.height = ( option.offsetTop + option.offsetHeight + 2 ) + "px";

if ( AC_isGecko )
{
AC_dropDownList.style.overflow = "-moz-scrollbars-vertical";
}
	
AC_dropDownList.style.overflowY = "scroll";
}

AC_MakeElementTreeUnselectable ( AC_dropDownList );

AC_dropDownList.setAttribute("selectedIndex", selectedIndex);
AC_Menu_SelectItem (AC_dropDownList, 0);

AC_dropDownList.style.visibility = "visible";

AC_dropDownList.setAttribute("selectedIndex", selectedIndex);


AC_PlaceDropDown ( editCtrl, true );
}


function AC_UpdateDropDown ( editCtrl, op )
{
if ( op == null || op == "" ||
editCtrl == null || editCtrl.value.length == 0 ||
AC_dropDownList == null || AC_dropDownList.childNodes.length == 0 )
{
AC_RemoveDropDown( editCtrl );
return;
}    

var selectedIndex = AC_dropDownList.getAttribute("selectedIndex");
if (selectedIndex == null)
{
selectedIndex = 0;
}

var newSelection = selectedIndex;

switch ( op )
{
case "selectPrev": newSelection--; break;
case "selectNext": newSelection++; break;
case "selectNextPage": newSelection += AC_MaxVisibleItems; break;
case "selectPrevPage": newSelection -= AC_MaxVisibleItems; break;
case "selectFirst": newSelection = 0; break;
case "selectLast": newSelection = AC_dropDownList.childNodes.length - 1; break;
default:
AC_RemoveDropDown( editCtrl );
return;
}

if (newSelection < 0)
{
newSelection = 0;
}

if (newSelection > (AC_dropDownList.childNodes.length - 1))
{
newSelection = (AC_dropDownList.childNodes.length - 1);
}

if ( newSelection != selectedIndex )
{
AC_Menu_SelectItem ( AC_dropDownList, newSelection, true );
AC_dropDownList.setAttribute("selectedIndex", newSelection);
}

AC_PlaceDropDown ( editCtrl, true );
}


function AC_PlaceDropDown ( editCtrl, forceIt )
{
if ( editCtrl == null && AC_dropDownList != null )
{
editCtrl = window.document.getElementById ( AC_dropDownList.getAttribute ( "editCtrlID" ));
}

if ( editCtrl == null || AC_dropDownList == null )
{
return;
}

if ( AC_dropDownDiv.style.visibility != "visible" && !forceIt )
{
return;
}


var left = window.document.body.clientLeft - AC_dropDownList.offsetLeft; // TODO: this actually fails on Moz, but the default layout saves us
var top = editCtrl.offsetHeight + window.document.body.clientTop - AC_dropDownList.offsetTop;
var parent = editCtrl;
do
{
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;
}
while (parent != null);

AC_dropDownDiv.style.left = left; 
AC_dropDownDiv.style.top = top;  
AC_dropDownDiv.style.visibility = "visible";

if (AC_dropDownIFrame != null) {
AC_dropDownIFrame.style.left = AC_dropDownDiv.style.left;
AC_dropDownIFrame.style.top = AC_dropDownDiv.style.top;
AC_dropDownIFrame.width = AC_dropDownDiv.offsetWidth;
AC_dropDownIFrame.height = AC_dropDownDiv.offsetHeight;
AC_dropDownIFrame.style.zIndex = editor.ComposeControl.style.zIndex + 1;
AC_dropDownDiv.style.zIndex = AC_dropDownIFrame.style.zIndex + 1;
AC_dropDownIFrame.style.visibility = "visible";

}

if (AC_dropDownList.offsetWidth < editCtrl.offsetWidth)
{
AC_dropDownList.style.posWidth = editCtrl.offsetWidth;
}

AC_dropDownList.setAttribute("editCtrlID",editCtrl.id);
}


function AC_RemoveDropDown()
{

BM_hide(false);

if ( AC_dropDownDiv != null )
{
AC_dropDownDiv.parentNode.removeChild ( AC_dropDownDiv );
AC_dropDownDiv.style.visibility = "hidden";
AC_dropDownDiv = null;
}

if ( AC_dropDownIFrame != null )
{
AC_dropDownIFrame.parentNode.removeChild(AC_dropDownIFrame);
AC_dropDownIFrame.style.visibility = "hidden";
AC_dropDownIFrame = null;
}

	
AC_dropDownList = null;
}

function AC_InsertSuggestion( editCtrl )
{
if ( AC_IsActive( ) == false )
{
return;
}
	
var cursorIndex = AC_GetCursorIndex(editCtrl);
if ( cursorIndex == -1 )
{
return;
}
	
var startDelim = -1;
substr = editCtrl.value.substring( 0, cursorIndex );
commaDelim = substr.lastIndexOf( ',' );
semiColonDelim = substr.lastIndexOf( ';' );
if ( semiColonDelim > commaDelim )
{
startDelim = semiColonDelim;
}
else
{
startDelim = commaDelim;
}
	
var stuffBeforeInsert = "";
if ( startDelim != -1 )
{
stuffBeforeInsert = editCtrl.value.substring( 0, startDelim + 1 ) + " ";
}
	
var stuffAfterInsert = editCtrl.value.substring( cursorIndex );

	
editCtrl.value = stuffBeforeInsert;
	
var item = AC_dropDownList.childNodes[AC_dropDownList.getAttribute("selectedIndex")];
editCtrl.value += item.text.replace(/\u00A0/g,"");

AC_selectedEmails [ AC_selectedEmails.length ] = AC_Rot13 ( AC_allCanons [ item.value+1 ]);
	
if ( stuffAfterInsert.length == 0 )
{
editCtrl.value += ', ';
}
else
{
editCtrl.value += stuffAfterInsert;
}
	
AC_RemoveDropDown();
editCtrl.focus();
}


var AC_updateTimer = null;
var AC_updateEditCtrl;
var AC_updateState;

function AC_KickNewDropDown( editCtrl, state )
{
if ( AC_updateTimer != null )
{
clearTimeout (AC_updateTimer);
}

AC_updateEditCtrl = editCtrl;
AC_updateState = state;

AC_updateTimer = setTimeout ( "AC_HandleNewDropDown()", 10 ); // fast typers will kill this
}

function AC_HandleNewDropDown()
{
var editCtrl = AC_updateEditCtrl, state = AC_updateState;

AC_ClearUpdate (); // clear first, as another might get created before we're done

if ( editCtrl != null )
{
AC_NewDropDown ( editCtrl, state );
}
}

function AC_ClearUpdate ()
{
if ( AC_updateTimer != null )
{
clearTimeout (AC_updateTimer);
AC_updateTimer = null;
}

AC_updateEditCtrl = null;
AC_updateState = null;
}



function AC_EmailExists( stringOfEmails )
{
var retVal = "";
var listOfEmails = stringOfEmails.split( ',' );


var emailExpr1 = new RegExp ( /([^@ ;<>]+@[^@ ;<>]+\.[^@ ;<>]+)/ ); // email alone
var whiteStrip = new RegExp ( /(\s*)/ ); // white space

for ( var index = 0; index < listOfEmails.length; index++ )
{
var email = listOfEmails[ index ];
var ematch = email.match ( emailExpr1 );

if ( ematch == null || ematch[1] == null || ematch[1] == "" )
{
var ematch = email.match ( whiteStrip );


if ( index < listOfEmails.length-1 || ematch == null || ematch[1] != email )
{
retVal += "0,";
}

continue;
}

email = ematch[1];
var found = false;


for ( var j = 0; j < AC_selectedEmails.length; j++ )
{
if ( email == AC_selectedEmails [j] )
{
found = true;
break;
}
}

if ( !found )
{
retVal += "0,";

}
else
{
if ( typeof window.document.Compose != "undefined" &&
typeof window.document.Compose.AC_Done != "undefined" &&
window.document.Compose.AC_Done != null &&
typeof window.document.Compose.AC_Done.value != "undefined" &&
window.document.Compose.AC_Done.value != 1 )
{
window.document.Compose.AC_Done.value = 1;
}
			

retVal += "1,";
}
}

if ( retVal == "" )
{
retVal = "0,";
}

return retVal;
}

function AC_PostProcess( )
{
if ( typeof window.document.Compose == "undefined" ||
typeof window.document.Compose.AC_Done == "undefined" ||
typeof window.document.Compose.AC_ToList == "undefined" ||
typeof window.document.Compose.AC_CcList == "undefined" ||
typeof window.document.Compose.AC_BccList == "undefined" ||
typeof AC_selectedEmails == "undefined" )
{
return;
}

if ( typeof AC_nickTokens == "undefined" /* && typeof AC_mostTokens == "undefined" */ )
{
return;
}

window.document.Compose.AC_Done.value = "";
window.document.Compose.AC_ToList.value = "";
window.document.Compose.AC_CcList.value = "";
window.document.Compose.AC_BccList.value = "";


var toField = window.document.getElementById("tofield");
	
if ( toField != null && 
window.document.Compose.AC_ToList != null &&
typeof window.document.Compose.AC_ToList != "undefined" &&
toField.value.length > 0 )
{
var binaryList = AC_EmailExists( toField.value );
if ( binaryList != null )
{
window.document.Compose.AC_ToList.value = binaryList;
}
}
	
var ccField = window.document.getElementById("ccfield");
	
if ( ccField != null &&
window.document.Compose.AC_CcList != null &&
typeof window.document.Compose.AC_CcList != "undefined" &&
ccField.value.length > 0 )
{
var binaryList = AC_EmailExists( ccField.value );
if ( binaryList != null )
{
window.document.Compose.AC_CcList.value = binaryList;
}
}
	
var bccField = window.document.getElementById("bccfield");
	
if ( bccField != null &&
window.document.Compose.AC_BccList != null &&
typeof window.document.Compose.AC_BccList != "undefined" &&
bccField.value.length > 0 )
{
var binaryList = AC_EmailExists( bccField.value );
if ( binaryList != null )
{
window.document.Compose.AC_BccList.value = binaryList;
}
}

}


AC_RotTable = { };

AC_LatinTable = [ ];

function AC_BuildTables ()
{
var s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", t = "abcdefghijklmnopqrstuvwxyz";

for ( var i=0; i<26; ++i )
{
AC_RotTable [s.charAt(i)] = s.charAt((i+13)%26);
AC_RotTable [t.charAt(i)] = t.charAt((i+13)%26);
}


AC_LatinTable[ 192 ] = AC_LatinTable[ 193 ] = AC_LatinTable[ 194 ] = AC_LatinTable[ 195 ] = AC_LatinTable[ 196 ] = AC_LatinTable[ 197 ] = "a";
AC_LatinTable[ 199 ] = "c";
AC_LatinTable[ 200 ] = AC_LatinTable[ 201 ] = AC_LatinTable[ 202 ] = AC_LatinTable[ 203 ] = "e";
AC_LatinTable[ 204 ] = AC_LatinTable[ 205 ] = AC_LatinTable[ 206 ] = AC_LatinTable[ 207 ] = "i";
AC_LatinTable[ 209 ] = "n";
AC_LatinTable[ 210 ] = AC_LatinTable[ 211 ] = AC_LatinTable[ 212 ] = AC_LatinTable[ 213 ] = AC_LatinTable[ 214 ] = AC_LatinTable[ 216 ] = "o";
AC_LatinTable[ 217 ] = AC_LatinTable[ 218 ] = AC_LatinTable[ 219 ] = AC_LatinTable[ 220 ] = "u";
AC_LatinTable[ 221 ] = "y";
AC_LatinTable[ 224 ] = AC_LatinTable[ 225 ] = AC_LatinTable[ 226 ] = AC_LatinTable[ 227 ] = AC_LatinTable[ 228 ] = AC_LatinTable[ 229 ] = "a";
AC_LatinTable[ 231 ] = "c";
AC_LatinTable[ 232 ] = AC_LatinTable[ 233 ] = AC_LatinTable[ 234 ] = AC_LatinTable[ 235 ] = "e";
AC_LatinTable[ 236 ] = AC_LatinTable[ 237 ] = AC_LatinTable[ 238 ] = AC_LatinTable[ 239 ] = "i";
AC_LatinTable[ 241 ] = "n";
AC_LatinTable[ 242 ] = AC_LatinTable[ 243 ] = AC_LatinTable[ 244 ] = AC_LatinTable[ 245 ] = AC_LatinTable[ 246 ] = AC_LatinTable[ 248 ] = "o";
AC_LatinTable[ 249 ] = AC_LatinTable[ 250 ] = AC_LatinTable[ 251 ] = AC_LatinTable[ 252 ] = "u";
AC_LatinTable[ 253 ] = AC_LatinTable[ 255 ] = "y";
	

}

AC_BuildTables();


function AC_Rot13( inputText ) {
if ( inputText == null ) return "";

var resultText = [];
var c, s;

for ( var i=0, n=inputText.length; i<n; ++i )
{
resultText [ i ] = ( s = AC_RotTable [(c = inputText.charAt(i))] ) ? s : c;

}


return resultText.join("");
}


function AC_DeLatin( inputText ) {
if ( inputText == null ) return "";

var resultText = [];

for ( var i=0, n=inputText.length; i<n; ++i )
{
var c = inputText.charCodeAt(i);
var sub = AC_LatinTable [c];
if ( sub == null ) sub = inputText.charAt(i);
resultText [ resultText.length ] = sub;
}


return resultText.join("");
}


function AC_DeLatinRot13( inputText ) {
if ( inputText == null ) return "";

var resultText = [];

for ( var i=0, n=inputText.length; i<n; ++i )
{
var c = inputText.charCodeAt(i);
var sub = AC_LatinTable [c];
if ( sub == null ) {
c = inputText.charAt(i);
sub = AC_RotTable [c];
if ( sub == null ) sub = c;
}
resultText [ resultText.length ] = sub;
}


return resultText.join("");
}


function AC_NextToken ( token ) {
while ( token.length > 0 ) {
var c = token.charCodeAt(token.length - 1);

if ( c < 65535 )
return token.substring ( 0, token.length - 1 ) + String.fromCharCode( c+1 );

token = token.substring ( 0, token.length - 1 );
}

return null;
}


function AC_DeLatinString ( input ) {
input = input.replace ( /[\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]/gi, "a" );
input = input.replace ( /[\u00E8\u00E9\u00EA\u00EB]/gi, "e" );
input = input.replace ( /[\u00E7]/gi, "c" );
input = input.replace ( /[\u00F1]/gi, "n" );
input = input.replace ( /[\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]/gi, "o" );
input = input.replace ( /[\u00F9\u00FA\u00FB\u00FC]/gi, "u" );
input = input.replace ( /[\u00FD\u00FF]/gi, "y" );
input = input.replace ( /[\u00C6]/gi, "\u00E6" ); // æ


return input;
}


function AC_InnerMatchString ( input )
{
input = input.replace( /([\\|\[|\]|\(|\)|\{|\}|\+|\.|\^|\$|\?])/g, "\\\$1");

input = input.replace ( /[a\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]/gi, "[a\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]" );
input = input.replace ( /[e\u00E8\u00E9\u00EA\u00EB]/gi, "[e\u00E8\u00E9\u00EA\u00EB]" );
input = input.replace ( /[c\u00E7]/gi, "[c\u00E7]" );
input = input.replace ( /[n\u00F1]/gi, "[n\u00F1]" );
input = input.replace ( /[o\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]/gi, "[o\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8]" );
input = input.replace ( /[u\u00F9\u00FA\u00FB\u00FC]/gi, "[u\u00F9\u00FA\u00FB\u00FC]" );
input = input.replace ( /[y\u00FD\u00FF]/gi, "[y\u00FD\u00FF]" );


return input;
}


function AC_OuterSearchExpr ( input )
{
var isDoubleByte = false;
for ( var index = 0; index < input.length; ++index )
{
if ( input.charCodeAt(index) > 127 )
{
isDoubleByte = true;
break;
}
}
	
if ( isDoubleByte == true )
{
var newInput = "";
for ( var index = 0; index < input.length; ++index )
{
if (input.charAt(index) == "\\")
{
newInput += "\\";
index++;
if (index >= input.length)
{
break;
}
}
newInput += input.charAt(index) + "\u00A0{0,1}";
}
input = newInput;
}
	
input = input.replace ( / /, " (\\S+ +<{0,1})*" );

return new RegExp ( "(^|[ <\"]|\u00A0)" + input, "gi" );
}


function AC_OuterMenuExpr ( input )
{
var isDoubleByte = false;
for ( var index = 0; index < input.length; ++index )
{
if ( input.charCodeAt(index) > 127 )
{
isDoubleByte = true;
break;
}
}

if ( isDoubleByte == true )
{
var newInput = "";
for ( var index = 0; index < input.length; ++index )
{
newInput += input.charAt(index) + "\u00A0{0,1}";
}
input = newInput;
}

input = input.replace(/</, "&lt;");

if ( input.search ( / / ) == -1 )
{
input += ")(.*)($";
}
else
{
input = input.replace(/ /," +)((?:\\S+ +(?:<|&lt;){0,1})*?)(" );
}

return new RegExp ( "(^|[ <\"]|&lt;|\u00A0)(" + input + ")", "gi" );
}



var AC_currentInput = null;
var AC_currentResults = null;
var AC_currentSuggestions = null;

var AC_substringMatches = { };
var AC_substringMatchesLinear = { };




function AC_CompileSuggestions ()
{
var inputText = AC_currentInput;
var searchResults = AC_currentResults;
if ( searchResults == null )
{
searchResults = AC_substringMatchesLinear[ inputText ];
}
	
if ( searchResults == null )
{
AC_currentSuggestions = null;
return null;
}

var suggestions = new Array( );

try
{
var matchExpr = AC_OuterMenuExpr ( AC_InnerMatchString ( inputText ));
}
catch(e)
{
var matchExpr = null; 
}


var total = 0;
var seenAddresses = [ ]; // TODO: this is index-based.  make it actual-email-based.

for ( var j=0; j < 2; ++ j )
{
if ( typeof AC_ignoreMaxResultItems == "undefined" ||
AC_ignoreMaxResultItems == null ||
AC_ignoreMaxResultItems == false )
{
if ( total >= AC_MaxResultItems )
{
break;
}
}

var isNick = ( j == 0 );

var matches = searchResults[j];
if ( matches == null ) continue;

if ( matches.start == null )
{
var fromList = matches;
indexes = { start: 0, end: fromList.length }
}

if ( fromList == null || fromList.length == 0 )
{
continue;
}



if ( searchResults[j+2] != null )
{
fromList = searchResults[j+2];
}
else
{
var sortEnd = indexes.start;
if ( typeof AC_ignoreMaxResultItems == "undefined" ||
AC_ignoreMaxResultItems == null ||
AC_ignoreMaxResultItems == false )
{
sortEnd += AC_MaxResultItems;
}
else
{
sortEnd += indexes.end;
}

if ( indexes.end < sortEnd )
{
sortEnd = indexes.end;
}

fromList = fromList.slice ( indexes.start, sortEnd );
fromList.sort (( typeof inputText.localeCompare == "function" ) ? AC_CompTokensByToken : AC_CompTokensByTokenIE5 );
searchResults[j+2] = fromList;
}

indexes = { start: 0, end: fromList.length };

for ( var index = indexes.start; index < indexes.end; index++ )
{
if ( typeof AC_ignoreMaxResultItems == "undefined" ||
AC_ignoreMaxResultItems == null ||
AC_ignoreMaxResultItems == false )
{
if ( total >= AC_MaxResultItems )
{
break;
}
}

var cIndex = fromList[ index ][1];
if ( cIndex == null ) continue;

if ( typeof seenAddresses [ cIndex ] != "undefined" ) // duplicate removal
{
continue;
}
			
seenAddresses [ cIndex ] = null;

if ( fromList [ index ][3] == null )
{
fromList [ index ][3] = AC_Rot13  ( AC_allCanons[ cIndex ] ).replace ( /"/g, "\\\"" );
}

var name = fromList [ index ][3];
			
if ( name.search  ( /[,";@]/ ) != -1 )
{
name = '"' + name + '"';
}

name = name.replace(/</g,"&lt;");
name = name.replace(/>/g,"&gt;");

if ( fromList [ index ][4] == null )
{
fromList [ index ][4] = AC_Rot13 ( AC_allCanons[ cIndex+1 ] );
}

var addr = fromList [ index ][4];
var isList = ( addr.length == 0 );
			
var suggestionText; // = name;
var menuText;

if ( typeof AC_insertEmailsOnly != "undefined" && AC_insertEmailsOnly == true )
{
if ( isList )
{
suggestionText = name;
}
else
{
suggestionText = addr;
}
				
addr = addr.replace(/</g,"&lt;");
addr = addr.replace(/>/g,"&gt;");
menuText = name + ( isList ? "" : ( " &lt;" + addr + "&gt;" ));
}
else
{
suggestionText = name + ( isList ? "" : ( " <" + addr + ">" ));
addr = addr.replace(/</g,"&lt;");
addr = addr.replace(/>/g,"&gt;");
menuText = name + ( isList ? "" : ( " &lt;" + addr + "&gt;" ));
}

if ( isNick )
{
var nick = AC_Rot13( fromList[ index ][0] );
if ( matchExpr )
{
nick = nick.replace ( matchExpr, "$1<b>$2</b>$3$4" );
}
				
menuText = [ "<i>", nick, AC_nickNameDisplayStr, "</i> - ", menuText ].join("");
}
else if ( isList )
{
if ( matchExpr )
{
name = name.replace ( matchExpr, "$1<b>$2</b>$3$4" );
}
				
menuText = [ "<i>", name, AC_listDisplayStr, "</i>" ].join("");
}
else
{
if ( matchExpr )
{
menuText = menuText.replace ( matchExpr, "$1<b>$2</b>$3<b>$4</b>" );
menuText = menuText.replace(/\u00A0/g,"");
}
}

suggestions [ suggestions.length ] = [ cIndex, suggestionText, menuText ];

total++;
}
}
	
AC_currentSuggestions = suggestions;
	
if ( suggestions.length == 0 )
{
return null;
}
	
return suggestions;
}




function AC_FindSuggestions( inputText )
{

if ( inputText != null )
{
inputText = AC_DeLatinString ( inputText.toLowerCase() );
}

if ( AC_currentInput != inputText )
{
AC_currentInput = inputText;
AC_currentResults = null;
AC_currentSuggestions = null;
}

if ( typeof AC_nickTokens == "undefined" /* && typeof AC_mostTokens == "undefined" */ )
{
return ( AC_currentSuggestions = null );
}

if ( inputText == null || inputText.length <= 0 || ( AC_nickTokens == null /* && AC_mostTokens == null */ ))
{
return ( AC_currentSuggestions = null );
}

{
AC_currentSuggestions = AC_FindLinear( inputText );
}
}


/*
function AC_FindBinary( inputText )
{
if ( AC_substringMatches[ inputText ] == null )
{

AC_substringMatches[ inputText ] = [ null, null ];

if ( inputText.length > 1 && ( window.document.Compose.Narrow == null || window.document.Compose.Narrow.checked ) ) {
var prefix = inputText.substring ( 0, inputText.length-1 );

if ( AC_substringMatches[ prefix ] == null )
AC_FindBinary( prefix ); // fast typing can cause this - recur

if ( AC_substringMatches[ prefix ][0] != null )
AC_FindBinaryTokens ( inputText, AC_nickTokens, AC_substringMatches[ prefix ][0], true );

if ( AC_substringMatches[ prefix ][1] != null && AC_substringMatches[ prefix ][1] != -1 )
AC_FindBinaryTokens ( inputText, AC_mostTokens, AC_substringMatches[ prefix ][1], false );
else
AC_FindBinaryTokens ( inputText, AC_mostTokens, { start: 0, end: AC_mostTokens.length }, false );

} else {

AC_FindBinaryTokens( inputText, AC_nickTokens, { start: 0, end: AC_nickTokens.length }, true );
if ( AC_substringMatches[ inputText ][0] != null && AC_substringMatches[ inputText ][0].length >= AC_MaxResultItems )
AC_substringMatches[ inputText ][1] = -1; // special value meaning "search not performed"
else
AC_FindBinaryTokens( inputText, AC_mostTokens, { start: 0, end: AC_mostTokens.length }, false );

}
}

AC_currentResults = AC_substringMatches[ inputText ];
}


function AC_FindBinaryTokens( inputText, fromList, fromRange, nicknames ) {
if ( fromRange == null )
{
fromRange = { "start": 0, "end": fromList.length };
}

var start = AC_TokenIndex ( inputText, fromList, fromRange.start, fromRange.end );
var end = fromRange.end;

if ( start >= end )
return;

var nextToken = AC_NextToken ( inputText );

if ( nextToken == null )
{
var newEnd = fromRange.end;
}
else
{
var newEnd = AC_TokenIndex ( nextToken, fromList, start, fromRange.end );
}

if ( newEnd == start )
{
AC_substringMatches[ inputText ][ nicknames?0:1 ] = null;
return;
}

if ( newEnd > start ) {
AC_substringMatches[ inputText ][ nicknames?0:1 ] = { "start": start, "end": newEnd };
return;
}


AC_Debug ( "fallback to linear search in the binary case\n" );

var encodedInputText = AC_DeLatinRot13 ( inputText );

for ( var index = start; index < end; index++ )
{
if ( fromList[ index ] == null || fromList[ index ][0] == null ||
fromList[ index ][0].length <= 0 )
{
continue;
}

var substrSuggestion = null;

substrSuggestion = fromList[ index ][0].substring( 0, encodedInputText.length );

if ( substrSuggestion == null || substrSuggestion.length <= 0 )
{
continue;
}


substrSuggestion = AC_DeLatin ( substrSuggestion.toLowerCase() );

if ( substrSuggestion.indexOf( encodedInputText ) != -1 )
{
if ( AC_substringMatches[ inputText ][nicknames?0:1] == null )
{
AC_substringMatches[ inputText ][nicknames?0:1] = new Array( );
}

var suggArr = AC_substringMatches[ inputText ][nicknames?0:1];
suggArr[ suggArr.length ] = fromList[ index ];
}
else
{
break;
}
}
}
*/

function AC_CleanRecipientValue ( fieldID ) {                          
var field = document.getElementById( fieldID );             
if ( field == null || field.value == null || field.value.length == 0 )
return;                                             
  
field.value = field.value.replace ( /(\n\r|\r\n|\s)/g, " " ).replace ( /;/g, "," ).replace( /,(,|\s)*,/g,",");
}



function AC_FindLinear ( inputText )
{
if ( AC_substringMatchesLinear[ inputText ] == null )
{
AC_substringMatchesLinear[ inputText ] = [ null, null ];
var matches = AC_substringMatchesLinear[ inputText ];


if ( inputText.length > 1 /*&& ( window.document.Compose.Narrow == null || window.document.Compose.Narrow.checked )*/ )
{
var prefix = inputText.substring ( 0, inputText.length-1 );

var prefixMatches = AC_substringMatchesLinear[ prefix ];
if ( prefixMatches == null )
{
AC_FindLinear( prefix ); // fast typing can cause this - recur
}

prefixMatches = AC_substringMatchesLinear[ prefix ];

if ( prefixMatches[0] != null )
{
if ( prefixMatches[0].length == 0 )
{
matches[0] = prefixMatches[0]; // recycle empty result arrays
}
else
{
matches[0] = AC_FindLinearTokens ( inputText, prefixMatches[0] );
}
}

if ( matches[0] != null && matches[0].length >= AC_MaxResultItems )
{
matches[1] = -1;
}
else if ( prefixMatches[1] != null && prefixMatches[1] != -1 )
{
if ( prefixMatches[1].length == 0 ) // recycle empty arrays
{
matches[1] = prefixMatches[1];
}
else
{
matches[1] = AC_FindLinearTokens ( inputText, prefixMatches[1] );
}
}
}

if ( matches[0] == null )
{
matches[0] = AC_FindLinearTokens( inputText, AC_nickTokens );
}

if ( matches[1] == null )
{
if ( matches[0] != null && matches[0].length >= AC_MaxResultItems )
{
matches[1] = -1; // special value meaning "search not performed"
}
else
{
matches[1] = AC_FindLinearCanons( inputText, AC_allCanons );
}
}
}

AC_currentResults = AC_substringMatchesLinear[ inputText ];
}


function AC_FindLinearTokens ( inputText, fromList )
{
var results = [ ], token;

var showAll = false;
if ( inputText == "\u0007" )
{
showAll = true;
}

var inputExpr = AC_OuterSearchExpr ( AC_Rot13 ( AC_InnerMatchString ( inputText ) ) );

if ( typeof AC_ignoreNickNames != "undefined" && AC_ignoreNickNames == true )
{
return;
}

for ( var i=0, n=fromList.length; i < n; i++ )
{
token = fromList[ i ];
if ( showAll == true || token[0].search( inputExpr ) != -1 )
{
results[ results.length ] = token;
}
}

return results;
}


function AC_FindLinearCanons ( inputText, fromList )
{
var results = [ ];
var name, email;

var showAll = false;
if ( inputText == "\u0007" )
{
showAll = true;
}

var inputExpr = AC_OuterSearchExpr ( AC_Rot13 ( AC_InnerMatchString ( inputText ) ) );

for ( var i=0, n=fromList.length; i<n; i+=2 )  // note increment - this is a canon list
{
var name = fromList[ i ];
var email = fromList[ i+1 ];

if ( showAll == true ||
name.search ( inputExpr ) != -1 ||
email.search ( inputExpr ) != -1 )
{
if ( email.length == 0 &&
typeof AC_ignoreLists != "undefined" && AC_ignoreLists == true )
{
continue;
}


if ( email.length > 0 )
{
name = [ name, " <", email, ">"].join("");
}


results[ results.length ] = [ name, i ];
}
}

return results;
}



function AC_Debug () {
var text = AC_Debug.arguments[0];

for ( var i=1, n=AC_Debug.arguments.length; i<n; ++i ) {
text += " " + AC_Debug.arguments[i];
}

}

function AC_SetInSelect( )
{
var targetElement = document.getElementById(AC_targetSelect);

if ( AC_currentSuggestions == null || AC_currentSuggestions.length == 0 )
{
return;
}

var selectedIndex = 0;

targetElement.innerHTML="";

for( var index = 0; index < AC_currentSuggestions.length; index++ )
{
optionText = AC_currentSuggestions[ index ][ 1 ].replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");

optionElement = document.createElement("option");
optionElement.setAttribute("value",optionText);
optionElement.setAttribute("title",AC_currentSuggestions[ index ][ 1 ]);
optionElement.innerHTML = optionText;

targetElement.appendChild(optionElement);
}
}

function AC_RemoveFromSelect( )
{
var targetElement = document.getElementById(AC_targetSelect);
var children = targetElement.childNodes;
	
for ( var index = 0, numChildren = children.length; index < numChildren; ++index )
{
targetElement.removeChild( children[ 0 ] );
}
}YAHOO.namespace('bm2');var Evt = YAHOO.util.Event;
var Dom = YAHOO.util.Dom;

/**
 * Add a whitespace trimming method to String.
 */
String.prototype.trim = function() {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}


/* SHARED UTILITIES */
YAHOO.bm2 = {
  config : {
   _IS_DEBUG : false,
   app : {
     version : null,
     current_folder_view_id : "",
     current_page_space_id : "",
     current_crumb_value : ""
   },
   dd : { //DRAG n DROP config
      _IS_ENABLED : true,
   	     
      DD_TARGETABLE_ELEMENT : { id: null, type: "A", className: "isTargetable", object_type : "DDBookmarkTarget",
      													activeBgColor:"#eee", inactiveBgColor:"#fff"	},
      DD_NONTARGETABLE_ELEMENT : { id: null, type: "A", className: "isNonTargetable"},
      
      DD_TARGETABLE_USER_GENERATED_PREFIX : "user-generated-folder",
      DD_TARGETABLE_FREQ_ACCESSED_FOLDER : "bb-folder-freq-accessed",
      DD_TARGETABLE_STATIC_PREFIX : "bb-folder-static",

      DD_BOOKMARKS_FOLDER_LIST_KEY : { key : "bm_folder_list" },
      DD_BOOKMARKS_TAGS_LIST_KEY : { key : "bm_tags_list" },
      
      //bookmark item
      DD_BOOKMARKS_CONTAINER : { id : "bookmarks", type : null, className : null },
      DD_BOOKMARKS_ELEMENT : { id : null, type : "DIV", className: "saveitem", id_prefix : "", 
      												object_type : "DDBookmark", hiddenClassName : "hide" },
        DD_BOOKMARKS_TITLE : { id : null, type : "A", className : "titlelink", id_prefix : "linkBM" },
        DD_BOOKMARKS_FOLDER : { id : null, type : "STRONG", className : "folder", id_prefix : null },
        DD_BOOKMARKS_CHECKBOX : { id : null, type : "INPUT", className : "chkbx", id_prefix : "selectBM" },
      
      //the dragged proxy element
      DD_BOOKMARKS_PROXY_ELEMENT : { id : null, type : "DIV", className: "draggedProxyElement"},
        DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS : { id : null, type : "UL", className: "extras"},
        DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS_ITEM : { id : null, type : "LI", className: ""},
      
      DD_FOLDERS_TAGS_CONTAINER : { id:"bb-folder-tag-container", type: "DIV", className : "mod",	activeQualifier:"dragging", inactiveQualifier:"" }, //root folder node 
      
      //folders
      DD_FOLDERS_CONTAINER : { id:"foldertree", type: null  }, //root folder node  
      DD_FOLDERS : { id : "folders", type : "DIV", className : "mod",	id_prefix : "bb-folder-", activeQualifier:"dragging", inactiveQualifier:"" },
      
      //tags
      DD_TAGS_CONTAINER : { id : "toptags", type : "DIV", className : null },
      DD_TAGS : { id : null, type : "A", className:null, id_prefix :"bb-tag-",	activeQualifier:"dragging", inactiveQualifier:"" },

      //these are page widgets
      DD_BB_DEBUG_LOG_ELEMENT : { id:"bb-error-log", type:"DIV", className:"" },
      DD_BB_DEBUG_LOG_EXCEPTION_ITEM : { id:null, type:"DIV", className:"exception" },
      DD_BB_PARENT_FOLDERS_LIST_ID : "user-created-rootfolder", //TODO: what does this do?
      DD_BB_OVERLAY_ELEMENT_ID : "bb_overlay_message",   
      DD_BB_OVERLAY_ELEMENT_MSG : { id:null, type:"STRONG" },
      DD_BOOKMARKS_ACTION_FORM : { id: "actionsform", type : "FORM" },
      DD_BB_CRUMBS_ELEMENT : { id:"crumbsactn", type:"INPUT" },
      DD_BB_BEACON_ELEMENT : { id:"linktrackbeacon", type:"IMG" },

      DD_PAGE_MAIN_ELEMENT : { id : "ybmpri", type : "DIV", className : null },
      DD_PAGE_SEC_ELEMENT : { id : "ybmsec", type : "DIV", className : null },
      DD_PAGE_UNCATEGORIZED_COUNT_ELEMENT : { id : "bb-folder-uncategorized-count", type: "SPAN", className : null },
      
			DD_CLASSNAMES_OF_UNDRAGGABLE_ELEMENTS : ['selectarea'],
      
      //bookmark styles
      height: "24em", // height of bookmark container
      transluscentBookmark : 0.76, //opacity style
      feature : {
        movingFolderTreeList : {
          _IS_ENABLED : true,
          _IS_USING_ANIMATION : true,
          animationInterval : 0.9,
          elementYOffset : 125,
          elementOpacity : 0.9
        },
        hiddenScrollHandler : {
          _IS_ENABLED : false,
          id : "bb_overlay_scroll_handler",
          percent_overlay : 0.2,
          checkHiddenScrollLayerTimerInterval : 100,
          upwardsBoundTimerInterval : 120,
          deltaY : -18
        }
      },//feature
      //proxy element styles
      offset_height_proxy_element : 4, //stupid HACK
      transluscentProxyElement : 0.45, //opacity style
      posDormantProxyElement : [-400,200], // this is the XY of the proxy element when it is NOT used

      footerEnabled : true, // don't show filters/pause/resume/clear UI
      verboseOutput : true, // TODO no clue
      logReaderEnabled : true, // pause right away (should be true all the time)

      isIE : (navigator.userAgent.toLowerCase().indexOf("msie") != -1),

      // supported Drag-n-Drop browser? -- this might be needed
      isSupportedDDUserAgent : function() { },

      _message_timeout_duration : 1.5,

      _proxy_element_attributes : {
        width: { value:320, unit:'px' },
        height: { value:16, unit:'px' },
        font: { value:11, unit:'px' }
      },
      // when the user has grabbed the bookmark and is looking to move to another folder
      _start_drag_attributes : {
        width: { from:400, to:300, unit:'px' },
        height: { from:80, to:16, unit:'px' },
        fontSize: { from:100, to:92, unit:'%' },
        duration: (this.isIE) ? 0.3: 0.45
      },
      // when the user has grabbed the bookmark and is looking to move to another folder
      _folder_treeview_list_move_attributes : {
          duration: (this.isIE) ? 0.3: 0.45
      },
      // when the user drops the bookmark on the target folder
      _dropped_drag_on_target_attributes : {
        height: { from:80, to: 0, units:'px' },
        fontSize: { from: 1, to: 0.10, unit: 'em' },
        opacity: { from: 1, to: 0 },
        duration : (this.isIE) ? 2.10 : 1.25
      },
      // when the user drops the bookmark on the target folder
      _set_normalized_page_height_attributes : {
        duration : (this.isIE) ? 2.1 : 1.2,
        magnitude : 1.5
      }
    }//dd
  },
  hp : 1,
  cp : 0,
  checkToolbar : function() {
    var cpre=/ CP=v=(\d+)&br=(.)/,cpv,cpbr,c=' '+ document.cookie;
    if (c.match(cpre)) {
      YAHOO.bm2.cp=1;
      cpv=RegExp.$1;
      cpbr=RegExp.$2;
      YAHOO.bm2.cp = ((cpbr=='i'&&cpv<60100) || (cpbr=='f'&&cpv<10201)) ? 0 : 1;
    }
  },
  /* BEACON CODE */
  beacon : function(psSEC, psSLK) {
    // skedaddle if there's no sec/slk info
    if (!psSEC || !psSLK) return;
    // get beacon node
    var sBeaconID = YAHOO.bm2.config.dd.DD_BB_BEACON_ELEMENT.id;
    var oBeacon = document.getElementById(sBeaconID);
    if (null != oBeacon && "undefined" != oBeacon) {
        oBeacon = YAHOO.bm2.createBeaconImg(sBeaconID);
        document.body.appendChild(oBeacon);
    }
    // make beacon
    var aData =[];
    aData = {'sec':psSEC,'slk':psSLK};
    aData[YAHOO.ULT.SRC_SPACEID_KEY] = YAHOO.bm2.util.getSpaceId();
    
    //var sUrl = window.location.hostname + window.location.pathname;
    //var sULTUrl =  YAHOO.ULT.track_click(sUrl,aData);
    
    var rBeaconl = YAHOO.ULT.beacon_click(aData, oBeacon);
  },
  createBeaconImg : function(psBeaconID) {
  	var oBeacon = null;
  	try {
	    // create the object
	    oBeacon = document.createElement(YAHOO.bm2.config.dd.DD_BB_BEACON_ELEMENT.type);
	    // give it attributes
	    oBeacon.id = psBeaconID;
	    oBeacon.style.height = '1px';
	    oBeacon.style.width = '1px';
	    oBeacon.style.border = 'none';
	    oBeacon.style.position = 'absolute';
	    oBeacon.style.top = '-100px';
	    oBeacon.style.left = '-100px';
  	}
  	catch (e) {
  		
  	}
    return oBeacon;
  }
}


/* DIG DEEPER */
YAHOO.bm2.digDeeper = function() {
    this.sMoreActId = 'moreddact';
    this.sMoreId = 'moredigdeeper';
    // add event listener
    this.oMoreAct = document.getElementById(this.sMoreActId);
    YAHOO.util.Event.addListener(this.oMoreAct, "click", this.expandOnClick, this);
}
YAHOO.bm2.digDeeper.prototype.expandOnClick = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get rid of event listeners
    YAHOO.util.Event.purgeElement(this);
    // turn actuator off
    if (this && this.style)
      this.style.display = 'none';
    // turn content on
    obj.oMore = document.getElementById(obj.sMoreId);
    if (obj.oMore) {
      obj.oMore.style.display = 'inline';
    } else {
}
}

/* GENERIC UTILITY FOR DOM */
YAHOO.bm2.getAncestorByClassName = function(psClassName, poThisNode) {
  var oAncestor = poThisNode.parentNode;
  if (!oAncestor) return;
  while (true) {
    // if match, return ancestor
    if (oAncestor.className.indexOf(psClassName)!=-1) {
      return oAncestor;
    }
    // if reach document.body, return false;
    if (oAncestor==document.body) {
      return false;
    }
    // otherwise, keep moving up
    oAncestor = oAncestor.parentNode;
  }
  return false;
}

// captures 'cancel' buttons and hits back
YAHOO.bm2.captureCancel = function(psID, psCancelClass) {
    if (!psID || !psCancelClass) return
    // add listeners to cancel buttons
    var aCancelBttns = YAHOO.util.Dom.getElementsByClassName(psCancelClass, 'input', psID);
    YAHOO.util.Event.addListener(aCancelBttns, 'click', YAHOO.bm2.handleCancel);
}
YAHOO.bm2.handleCancel = function(e) {
    // cancel default behaviour
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false; 
    // return to previous history item
    history.back();
}

/* dismiss sidenav promotion */
YAHOO.bm2.sidenavPromo = function() {
    // get close button
    sCloseBttnId = 'sidenavclose';
    oCloseBttn = document.getElementById(sCloseBttnId);
    // add event listener
    YAHOO.util.Event.addListener(oCloseBttn, "click", this.handleClose, this);
}
// close sidenav and set cookie on click event
YAHOO.bm2.sidenavPromo.prototype.handleClose = function(e, obj) {
    // cancel default behaviour
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // set up vars we'll use
    var sCookieName = 'ybm_sidenavPromo01'
    var sPromoModId = 'promo';
    // close module
    var oPromo = document.getElementById(sPromoModId);
    if (oPromo) {
        oPromo.style.display = 'none';
    }
    // save cookie off
    var nextyear = new Date();
    nextyear.setFullYear(nextyear.getFullYear() +1);

    // clear previous cookie
    var clearCookieStr = sCookieName +"="+ true;
    clearCookieStr += '; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
    document.cookie = clearCookieStr;

    // set real cookie
    var cookieString = sCookieName +"="+ true;
    cookieString += "; path=/; domain=.bookmarks.yahoo.com; expires="+ nextyear.toGMTString();
    document.cookie = cookieString;

}


/* array functions */
// Mozilla 1.8 has support for indexOf, lastIndexOf, forEach, filter, map, some, every
// http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (obj, fromIndex) {
        if (fromIndex == null) {
            fromIndex = 0;
        } else if (fromIndex < 0) {
            fromIndex = Math.max(0, this.length + fromIndex);
        }
        for (var i = fromIndex; i < this.length; i++) {
            if (this[i] === obj)
                return i;
        }
        return -1;
    };
}
Array.prototype.remove = function (obj) {
    var i = this.indexOf(obj);
    if (i != -1)
        this.splice(i, 1);
};

// do this stuff
YAHOO.bm2.checkToolbar();

document.write('<style type="text/css">');
if (YAHOO.bm2.cp) {
    document.write('.hastoolbar{display:none}');
    document.write('.notoolbar{display:block}');
} else {
    document.write('.hastoolbar{display:block}');
    document.write('.notoolbar{display:none}');
}
document.write('</style>');/**
  @description performancePrefs
 */
YAHOO.bm2.performancePrefs = {
    /**  
     * Initialize elements on the page 
     */
    init : function(loadOptions) {
        // make element visible (don't bother for Safari, it can't use this stuff anyway)
        var _prefForm = Dom.get('performance_prefs');
        if (_prefForm && _prefForm.style && !Evt.isSafari)
            _prefForm.style.display = 'block';
        // add eventListener to submit bttn
//        var _submitBttn = Dom.get('performanceSubmit');
//        Evt.on(_submitBttn, 'click', this.handleSubmit, this);
    },
    
    /**
     * Event Handler for submit button
     */
    handleSubmit : function(e, obj) {
        // cancel out default submit behaviour
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false;
        // get Drag 'n Drop setting and deal with it
        var _DNDSelect = Dom.get('disableDragNDrop');
        if (_DNDSelect)
            obj.saveDragNDrop(_DNDSelect);
        // message user save is complete
        var _messageObj = Dom.get('perfMessages');
        if (_messageObj && _messageObj.style)
            _messageObj.style.display = 'block';
    },

    /**
     * SAVE Drag 'n Drop settings via cookie
     */
    saveDragNDrop : function(selectObj) {
        // get setting (true = disable | false = enable)
        var _inputValue = (selectObj.checked) ? 'true' : 'false';
        // write a cookie with new name
        var _nextYear = new Date();
        _nextYear.setFullYear(_nextYear.getFullYear() +1);

        // clear previous cookie
        var clearCookieStr = 'ybm_prefsDisableDND' + '='+ _inputValue;
        clearCookieStr += '; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
        document.cookie = clearCookieStr;

        // set real cookie
        var _cookieString = 'ybm_prefsDisableDND' + '='+ _inputValue;
        _cookieString += '; path=/; domain=.bookmarks.yahoo.com; expires='+ _nextYear.toGMTString();
        document.cookie = _cookieString;
    }

}

/**
  @description BookmarksManager
 */
YAHOO.bm2.BookmarksManager = {
    DD_BOOKMARKS_ACTION_MOVE_TO : "moveto",
    DD_BOOKMARKS_ACTION_ADD_TAGS : "addtags",
    ONLOAD_SECONDARY_COLUMN_HEIGHT : 0,
    _IS_DEBUG : false,

    _manager : null,
    _bookmarks : [],
    _folders : [],
    _tags : [],
    _selected_bookmarks : null,

    isDragging : false,
    setIsDragging : function(pBool) { YAHOO.bm2.BookmarksManager.isDragging=pBool; },
    getIsDragging : function() { return YAHOO.bm2.BookmarksManager.isDragging; },

    isInUpwardsBound : false,
    upwardsBoundTimer : null,
    checkHiddenScrollLayerTimer : null,

		doCaptureKeystrokeInit : function() {
			//document.onkeyup = function(e) { YAHOO.bm2.BookmarksManager.doHandleKeystroke(e)  };
		},
		doHandleKeystroke : function(e) {
			var _event = e ? e.which : window.event.keyCode;
			if (113 == _event) {
				//TODO:handle keystroke
			}
		},
		
		doToggleTagView : function(pLink) {
			try {
				if (!pLink) return;
				var _link = pLink;
				var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_TAGS_CONTAINER.id);
				//var _unordered_list = _ele.getElementsByTagName('UL')[0];
				if (null != _ele && "undefined" != _ele) {
					var _isListView = ("listview" == _ele.className); //if current view is cloud view
					_ele.className = (_isListView) ? "cloudview" : "listview";
					_link.innerHTML = (_isListView) ? bm2_translations.messages.MSG_LIST_VIEW : bm2_translations.messages.MSG_CLOUD_VIEW;
				  _link.blur();
				  YAHOO.bm2.util.setCookie('ybm_liststyle',((_isListView) ? 'usetagscloud' : 'usetags'));
          YAHOO.bm2.BookmarksManager.debug("isListView: " + ((_isListView) ? 'usetagscloud' : 'usetags'));
				}
			} 
			catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
			}
			
		},
		
		getCrumbValue : function() {
			var _crumbs = YAHOO.bm2.config.app['current_crumb_value'];
			if (null != _crumbs && "" != _crumbs) {
				return _crumbs;
			}
			return null;
		},
		
		getQueryStringValue : function(pKey,pUrl) {
			var _qt = pUrl.split("?")[1];
			var _kv = _qt.split("&");
			for (var _i=0;_i<_kv.length;_i++) {
				var _v = _kv[_i].split('=');
				if (_v[0].toUpperCase() == pKey.toUpperCase()) return _v[1];
			}
			return "";
		},
		
    quantify : function() {
    	var _isBling = (window.location.search.indexOf("bling=on") != -1);
    	if (_isBling) {
    		try {
	    		var _ele = document.getElementById('quantifier');
	    		if (null != _ele && "undefined" != _ele) {
	    		  var _parent_ele = _ele.parentNode;
	    		    if (null != _parent_ele && "undefined" != _parent_ele) {
	    		    var _tmpStr = _parent_ele.className + " bling";
	    		    _parent_ele.className = _tmpStr;
	    		    _welcome_ele = document.getElementById('welcome');
	    		    if (null != _welcome_ele && "undefined" != _welcome_ele) {
	    		    	var _tmp_html = new String(_welcome_ele.innerHTML);
	              var _foo_html = _tmp_html.replace("Welcome","Whadadillieyo");
	              _foo_html = _foo_html.replace("Sign out","Audi 5000");
	              _welcome_ele.innerHTML = _foo_html;
	    		    }
	    		  }
	    		}
    		}
    		catch(e) {
          YAHOO.bm2.BookmarksManager.debug(e,true);    			
    		}
    	}    	
    },

    handleException : function(pE) {
      this.debug(pE);
    },

    debug : function(pE,isException) {
      if (this._IS_DEBUG) {
        var _exception_style = (isException) ? YAHOO.bm2.config.dd.DD_BB_DEBUG_LOG_EXCEPTION_ITEM.className : "";
        try {
          var _msg = ("object" == typeof pE) ? pE.message : pE
          var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_BB_DEBUG_LOG_ELEMENT.id);
          if (null != _ele && "undefined" != _ele) {
            var _html = _ele.innerHTML;
            _ele.innerHTML = '<' + YAHOO.bm2.config.dd.DD_BB_DEBUG_LOG_EXCEPTION_ITEM.type + ' class="' + _exception_style + '">' + _msg + '</' + YAHOO.bm2.config.dd.DD_BB_DEBUG_LOG_EXCEPTION_ITEM.type + '>' + _html;
          }
        }
        catch (e) {
          alert("CRITICAL ERROR: YAHOO.bm2.BookmarksManager.debug() method has failed");
        }
        finally {
          _msg = null;
          _ele = null;
          _html = null;
        }
      }
    },

    getYUIInstanceDDManager : function() {
      return YAHOO.util.DDM;
    },

    /*  @returns reference to the bm2_inline_actions object
     * */
    getInlineActionsManager : function() {
      var _inline_actions_mgr = YAHOO.bm2.thisInlineAction;
      try {
        if (null!=_inline_actions_mgr && "undefined"!=_inline_actions_mgr) {
          return _inline_actions_mgr;
        }
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _inline_actions_mgr = null;
      }
      return null;
    },

    /*  @returns reference to the bm2_buffer object
     * */
    getBuffer : function() {
      var _buffer = YAHOO.bm2.bmBuffer;
      if (null != _buffer && "undefined"!=_buffer) {
        return _buffer;
      }
      return null;
    },

		getActionsForm : function() {
			var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_BOOKMARKS_ACTION_FORM.id);
			if (null != _ele && "undefined"!=_ele) return _ele;
			return null;
		},

    pagination : {
      handler : {
        _page_total : -1,
        _page_start : -1,
        _page_end : -1,
        _page_offset : -1,

        setConfig : function(pConfig) {
          var _config = pConfig;
          this._page_total = _config['page_total'] ;
        }
      },

      getTotal : function() {
        var _buffer = this.getBuffer();
        var _count = -1
        try {
          _count = _buffer.totalcount;
        }
        catch(e) {
          YAHOO.bm2.BookmarksManager.debug(e,true);
        }
        finally {
          _buffer = null;
        }
        return _count;
      },
      setCountDisplay : function(pDelta) {
        var _change = pDelta; // can be negative
        //YAHOO.bm2.BookmarksManager.getInlineActionsManager().getBookmarks().actionBackfill();
        YAHOO.bm2.BookmarksManager.getInlineActionsManager().getBookmarks().updateInfoBar(_change);
      }
    },

    setVisibleBookmarks : function(pNumber) {
      var _num = parseInt(pNumber);
      if (isNaN(_num)) return;
      var _bookmarks = this.getBookmarks();
      var _c_bookmarks = this.getBookmarksCount();
      var _j=0;
      var _ele = null;
      try {
        for (var key in _bookmarks) {
          _ele = document.getElementById(key);
          if (null!=_ele && "undefined"!=_ele &&
              _ele.className.indexOf(YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.className) != -1 &&
              _ele.className.indexOf(YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.hiddenClassName) != -1
          ) {
            _ele.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.className;
            _j++;
          }
          if (_j >= _num) break; //let's not go overboard
        }
      }
      catch(e) {
        //TODO:handle exception
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _bookmarks = null;
        _c_bookmarks = null;
        _ele = null;
      }
    },

    /* @returns (ArrayList) bookmark keys
     * @param additional key to add (optional)
     */
    parseCheckedBookmarks : function(pKey) {
      this.setCheckedBookmarks([]);//reset the selected bookamrks
      var _aChecked = YAHOO.util.Dom.getElementsByClassName(YAHOO.bm2.config.dd.DD_BOOKMARKS_CHECKBOX.className,
                                                            YAHOO.bm2.config.dd.DD_BOOKMARKS_CHECKBOX.type,
                                                            YAHOO.bm2.config.dd.DD_BOOKMARKS_CONTAINER.id);
      var _c_aChecked = _aChecked.length;
      var _a_List = []; //list of selected bookmarks keys to return
      var _bookmarks = this.getBookmarks(); //let's get some bookmarks
      var _current_id = null;
      var _ele = null;
      var _isEnteringHiddenBookmarks = false; //WTF does this do?

	    try {
	      //the additional key needs to be added first
	      var _key = (null != pKey && "" != pKey) ? pKey : null;
	      if (null != _key) _a_List.push(_bookmarks[_key]);
	
	      for (var _i=0; _i <_c_aChecked; _i++) {
	        if (_isEnteringHiddenBookmarks) break;
	        if (_aChecked[_i].checked) {
	          _current_id = _aChecked[_i].id.substr(YAHOO.bm2.config.dd.DD_BOOKMARKS_CHECKBOX.id_prefix.length);
	          if (null != _key && _current_id.toLowerCase().indexOf(_key.toLowerCase()) != -1) continue;
	          _a_List.push(_bookmarks[_current_id]);
	          _ele = document.getElementById(_key);
	          if (null!=_ele && "undefined"!=_ele &&
	            _ele.className.indexOf(YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.hiddenClassName) != -1) {
	            _isEnteringHiddenBookmarks = true;
	          }
	        }
	      }
	    }
	    catch(e){
	      //TODO:handle exception
	      this.debug(e,true);
	    }
	    finally {
        _aChecked = null;
        _c_aChecked = null;
        _key = null;
        _bookmarks = null;
        _current_id = null;
    	}
    	return _a_List;
  	},

    /*	@returns Arraylist
     * */
  	getCheckedBookmarkKeys : function() {
      var _a_List = [];
      var _checked_bookmarks = YAHOO.bm2.BookmarksManager.getCheckedBookmarks();
      for (var key in _checked_bookmarks) {
        if (null!=_checked_bookmarks[key] && "undefined"!=_checked_bookmarks[key] && ""!=_checked_bookmarks[key]) {
          _a_List.push(_checked_bookmarks[key].id);
        }
      }
      _checked_bookmarks = null;
      return _a_List;
    },

    getCheckedBookmarks : function() { return this._selected_bookmarks; },
    setCheckedBookmarks : function(pData) { this._selected_bookmarks = pData; },
    resetCheckedBookmarks : function() {
      var _data = this.getCheckedBookmarks();
      var _c_data = _data.length;
      var _ele_prefix_name = YAHOO.bm2.config.dd.DD_BOOKMARKS_CHECKBOX.id_prefix;
      var _ele = null;
      try {
        if (_c_data > 0) {
          for (var _i=0;_i<_c_data;_i++) {
            _ele = document.getElementById(_ele_prefix_name + _data[_i].getId());
            if (null != _ele && "undefined" != _ele) {
              if (_ele.checked) _ele.click(); //_ele.checked = false;
            }
          }
        }
        this.setCheckedBookmarks([]);
      }
      catch(e) {
        this.debug(e,true);
      }
      finally {
        _data = null;
        _ele_prefix_name = null;
        _ele = null;
      }
    },

    getBookmarksCount : function() {
      var _i=0;
      var _bookmarks = this.getBookmarks();
      for (var _key in _bookmarks) if (null!=_bookmarks[_key]) _i++;
      _bookmarks = null;
      return _i;
    },
    getBookmarks : function() { return this._bookmarks; },
    setBookmarks : function(pData) { this._bookmarks = pData; this.debug("set " + this.getBookmarksCount() + " bookmarks"); },

    getTagsCount : function() { return this.getTags().length; },
    getTags : function() { return this._tags; },
    setTags : function(pData) { this._tags = pData; this.debug("set " + this.getTagsCount() + " tags"); },
    
    getFoldersCount : function() {
      var _i=0; var _folders = this.getFolders();
      for (var _key in _folders) if (null!=_folders[_key]) _i++;
      _folders = null;
      return _i;
    },
    getFolders : function() { return this._folders; },
    setFolders : function(pData) { this._folders = pData; this.debug("set " + this.getFoldersCount() + " folders"); },

    getFolderByKey : function(pKey) {
      var _folders = this.getFolders();
      var _folder = null;
      for (var _key in _folders) {
        if (pKey.toString() == _key) {
          _folder = _folders[_key];
          break;
        }
      }
      return _folder;
    },
    setOpacity : function(pEle,pNum) {
      if (isNaN(parseInt(pNum))) return;
      if (null!=pEle && "undefined"!=pEle)  {
        var _tmp_opacity = pNum;
        try {
          pEle.style.opacity = _tmp_opacity;
          pEle.style.filter = "alpha(opacity="+(_tmp_opacity * 100)+")";
        }
        catch(e) {
          YAHOO.bm2.BookmarksManager.debug(e);
        }
        finally {
          _tmp_opacity = null;
        }
      }
    },

    /*    @return (void)
     *    @description set mouse cursor
     * */
    setCursor : function(pEle,pVal) {
      var _e = (null!=pEle && "undefined"!=pEle) ? pEle : document.body;
      var _val = pVal;
      var _isGecko = (navigator.userAgent.toLowerCase().indexOf("gecko") != -1); //-moz-grab, -moz-grabbing
      switch (pVal) {
        case this.EVENT_TYPE_GRAB:
          _val = "move";
          break;
        case this.EVENT_TYPE_DRAGGING:
          _val = "default";
          break;
        case this.EVENT_TYPE_DEFAULT:
        default:
          _val = "default";
          break;
      }
      try {
        if (_e.style) _e.style.cursor = _val;
        else _e.cursor = _val;
      }
      catch (e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _e = null; _val = null; _isGecko = null;
      }
    },
      
    setNormalizedPageHeight : function(pFolderTagContainerElement) {    	
			var _ele = pFolderTagContainerElement || document.getElementById(YAHOO.bm2.config.dd.DD_FOLDERS_TAGS_CONTAINER.id);
			var	_ele_offsetHeight = parseInt(_ele.offsetHeight);
      var _main_column_ele = null;
      var _sec_column_ele = null;
      var _node = null;

      _main_column_ele = document.getElementById(YAHOO.bm2.config.dd.DD_PAGE_MAIN_ELEMENT.id);
      _main_column_ele_height = parseInt(_main_column_ele.offsetHeight);

      _sec_column_ele = document.getElementById(YAHOO.bm2.config.dd.DD_PAGE_SEC_ELEMENT.id);
      _sec_column_ele_height = parseInt(_sec_column_ele.offsetHeight);

			var _sec_children_offsetHeight = 0;

			for (var _i=0; _i<_sec_column_ele.childNodes.length; _i++) {
          _node = _sec_column_ele.childNodes[_i];
          if ("DIV" == _node.tagName) {
          	_sec_children_offsetHeight += parseInt(_node.offsetHeight);
          }
      }
      //if (_sec_children_offsetHeight > _sec_column_ele_height) _sec_column_ele_height = _sec_children_offsetHeight;
      
      YAHOO.bm2.BookmarksManager.debug(_sec_children_offsetHeight + " :: " + _main_column_ele_height + " :: " + _sec_column_ele_height);
      
      var _tmp_height = (_sec_children_offsetHeight > _sec_column_ele_height) ? _sec_children_offsetHeight :_sec_column_ele_height;
      var _tmp_end_height = 0;
        
		  //if main right column is bigger than left column
      if (_main_column_ele_height > _tmp_height) {
        _sec_column_ele.style.height = (parseInt(document.body.offsetHeight) - (parseInt(_sec_column_ele.offsetTop)*2)).toString() + "px";
      }
      else if (_main_column_ele_height < _tmp_height) { 
      	_tmp_end_height = (_sec_children_offsetHeight > _main_column_ele_height ) ? _sec_children_offsetHeight : _main_column_ele_height; 
        //var _tmp_height = _main_column_ele_height;
      	var _move_empty_whitespace = new YAHOO.util.Anim(_sec_column_ele, { height: { from: _tmp_height, to: _tmp_end_height } }, 0.7 ,YAHOO.util.Easing.easeOutStrong);
        _move_empty_whitespace.animate();
        //this is the original call to set the top style 
      	//_ele.parentNode.style.height = _main_column_ele_height.toString() + "px";
      	setTimeout(function() {_sec_column_ele.style.height = "auto";}, 1000);  
      }
    	
    },

    doMoveFoldersTreeList : function(pBool,pObject) {
      var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_FOLDERS_TAGS_CONTAINER.id);
      var _ele_offsetHeight = 0;
      var _obj = YAHOO.bm2.BookmarksManager.getYUIInstanceDDManager().dragCurrent; //pObject||null;
      if (null != _ele && "undefined" != _ele) {
        if (!pBool) {
          _ele.style.top = "0px"; // reset the folders list
          _ele.className = YAHOO.bm2.config.dd.DD_FOLDERS_TAGS_CONTAINER.className;
          YAHOO.bm2.BookmarksManager.setOpacity(_ele,1);
        }
        else {
          this.setNormalizedPageHeight(_ele);
          try {
            var _offHeight = 0;

            _offHeight = (document.all) ? ((document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) : window.pageYOffset;
            var _y = YAHOO.bm2.config.dd.feature.movingFolderTreeList.elementYOffset;
            if (_offHeight > _y) _offHeight -= _y;

            if (YAHOO.bm2.config.dd.feature.movingFolderTreeList['_IS_USING_ANIMATION']) {
              var _move_the_tree_list = new YAHOO.util.Anim(_ele, { top: { from: 0, to: (_offHeight) } }, YAHOO.bm2.config.dd.feature.movingFolderTreeList.animationInterval ,YAHOO.util.Easing.easeOutStrong);
              _move_the_tree_list.onComplete.subscribe(YAHOO.bm2.BookmarksManager.resetDDManagerConstraints,null);
              _move_the_tree_list.animate();
            }
            else {
              _ele.style.top = _offHeight.toString() + "px";
              YAHOO.bm2.BookmarksManager.resetDDManagerConstraints();
            }

            _ele.className = YAHOO.bm2.config.dd.DD_FOLDERS_TAGS_CONTAINER.className + " " + YAHOO.bm2.config.dd.DD_FOLDERS_TAGS_CONTAINER.activeQualifier;
            YAHOO.bm2.BookmarksManager.setOpacity(_ele,YAHOO.bm2.config.dd.feature.movingFolderTreeList.elementOpacity);

          }
          catch(e) {
            //TODO:handle exception
            YAHOO.bm2.BookmarksManager.debug(e,true);
          }
          finally {
            _ele = null;
            _wih = null;
            _offHeight = null;
            _move_the_tree_list = null;
          }
        }
      }
    },

    resetDDManagerConstraints : function(pEventType,pObj) {
      var _obj = YAHOO.bm2.BookmarksManager.getYUIInstanceDDManager().dragCurrent;      
      //this condition happens when the user drags and releases
      //before the animation finishes
      if (!YAHOO.bm2.BookmarksManager.getIsDragging()) {
        YAHOO.bm2.BookmarksManager.doMoveFoldersTreeList(false,null);
      }
      try {
        YAHOO.util.DDM.refreshCache(_obj.groups);
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
    },

    /*  @description this routine sets the hidden layer relative to the viewport
     */
    doHandleScrollLayerWhileDragging : function() {
      if (YAHOO.bm2.config.dd.feature.hiddenScrollHandler._IS_ENABLED) {
        var _ele = document.getElementById(YAHOO.bm2.config.dd.feature.hiddenScrollHandler.id);
        if (null != _ele && "undefined" != _ele) {
          try {
            var _wih = -1;
            var _offHeight = 0;
            _offHeight = (document.all) ? ((document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) : window.pageYOffset;
            _wih = (window.innerHeight) ? window.innerHeight : document.body.clientHeight;
            // YAHOO.bm2.BookmarksManager.debug("window dimensions: _wih: " + _wih + ", _offHeight: " + _offHeight);
            if (-1 != _wih && _wih > 100) {
              _ele.style.top = (_offHeight + (_wih - (_wih - (YAHOO.bm2.config.dd.feature.hiddenScrollHandler.deltaY / 4)))) + "px";
            }
          }
          catch(e) {
            //TODO:handle exception
            YAHOO.bm2.BookmarksManager.debug(e,true);
          }
          finally {
            _ele = null;
            _wih = null;
            _offHeight = null;
          }
        }
      }
    },

    // called once in DDBookmark.startDrag() and once during endDrag()
    setVisibilityScrollLayer : function(pBool) {
      if (YAHOO.bm2.config.dd.feature.hiddenScrollHandler._IS_ENABLED) {
        var _ele = null;
        var _viewport_height = YAHOO.util.Dom.getViewportHeight();
        _ele = document.getElementById(YAHOO.bm2.config.dd.feature.hiddenScrollHandler.id);
        _ele.style.visibility = (pBool) ? "visible" : "hidden";
        _ele.style.height = Math.floor(_viewport_height * YAHOO.bm2.config.dd.feature.hiddenScrollHandler.percent_overlay).toString() + "px";
        _ele.style.zIndex = 1401;
        if (pBool) {
          try {
            YAHOO.bm2.BookmarksManager.checkHiddenScrollLayerTimer = setInterval(function(){YAHOO.bm2.BookmarksManager.doHandleScrollLayerWhileDragging();}, (YAHOO.bm2.config.dd.feature.hiddenScrollHandler.checkHiddenScrollLayerTimerInterval.toString() + "px"));
          }
          catch(e) {
          //TODO:handle exception
          YAHOO.bm2.BookmarksManager.debug(e,true);
          }
          finally {
              _ele = null;
              _viewport_height = null;
          }
        }
        else {
          try {
            clearInterval(YAHOO.bm2.BookmarksManager.checkHiddenScrollLayerTimer); // turn off the timer that checks the hidden layer's [x,y]
            YAHOO.bm2.BookmarksManager.endScroll();
          }
          catch(e) {
          //TODO:handle exception
          YAHOO.bm2.BookmarksManager.debug(e,true);
          }
          finally {
            _ele = null;
            _viewport_height = null;
          }
        }
      }
    },

    startScroll : function() {
      try {
        YAHOO.bm2.BookmarksManager.debug("startScroll");
        YAHOO.bm2.BookmarksManager.upwardsBoundTimer = setInterval(function() { window.scrollBy(0,(YAHOO.bm2.config.dd.feature.hiddenScrollHandler.upwardsBoundTimerInterval.toString() + "px")); });
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
      }
    },

    endScroll : function() {
      try {
        YAHOO.bm2.BookmarksManager.debug("endScroll");
        clearInterval(YAHOO.bm2.BookmarksManager.upwardsBoundTimer);
      }
      catch(e) {
         YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
      }
    },

    /*	@returns (boolean)
     *  @description starts the DD manager
     * */
    init : function(pData) {
    	if (YAHOO.bm2.config.dd._IS_ENABLED) {
        this._manager = YAHOO.bm2.util.DDInit.init(pData);
    	  return true;
    	}
    	return false;
    },

    /* UI overlay messages */
    overlay_message : null,
    isLoading : false,

    getIsLoading : function() { return this.isLoading; },
    setIsLoading : function(pBool) { this.isLoading = pBool; },
    setStateDefault : function() { this.setIsLoading(false); },
    setStateLoading : function() { this.setIsLoading(true); },

    setUIMessage : function(pStr,pIconStatus) {
      var _msg = '<' + YAHOO.bm2.config.dd.DD_BB_OVERLAY_ELEMENT_MSG.type + ' class="'+pIconStatus+'">'+ pStr +'</'+ YAHOO.bm2.config.dd.DD_BB_OVERLAY_ELEMENT_MSG.type +'>';
      return _msg;
    },

    setUIMessageError : function() {
    	var _msg = YAHOO.bm2.BookmarksManager.setUIMessage(bm2_translations.messages['MSG_FAILURE_FATAL_EXCEPTION'],'exception');
      YAHOO.bm2.BookmarksManager.displayOverlay(true,_msg);
      setTimeout(function(){ YAHOO.bm2.BookmarksManager.displayOverlay(false,null); },(YAHOO.bm2.config.dd._message_timeout_duration*3000));
    },

    // singleton to get overlay layer
    getOverlay : function() {
      try {
        if (null==this.overlay_message) {
          this.overlay_message = new YAHOO.widget.Overlay(YAHOO.bm2.config.dd.DD_BB_OVERLAY_ELEMENT_ID);
        }
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      return this.overlay_message;
    },

    displayOverlay : function(pIsDisplayed,pMessage) {
      var _isDisplayed = pIsDisplayed || false;
      var _overlay = YAHOO.bm2.BookmarksManager.getOverlay();
      try {
        if (!_isDisplayed) _overlay.cfg.setProperty("y", -200);
        //_overlay.center();
        _overlay.cfg.setProperty("fixedcenter", _isDisplayed);
        _overlay.visible = _isDisplayed;
        if (null != pMessage) _overlay.setBody(pMessage);
      }
      catch(e) {
        //TODO:handle exception
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally{
        _overlay = null;
      }
    },

    removeDDBookmarkFromDOM : function(pEventType,pObject) {
      var _ele = this.getEl();
      try {
        if (null != _ele && "undefined" != _ele) {
          if (null != _ele.parentNode && "undefined" != _ele.parentNode) _ele.parentNode.removeChild(_ele);
        }
      }
      catch(e) {
      	YAHOO.bm2.BookmarksManager.debug(e,true);
      }
    },

    removeBookmarkFromDOM : function(pEventType,pObjectScope) {
      var _ele = pObjectScope;
      try {
        if (null != _ele && "undefined" != _ele) {
          if (null != _ele.parentNode && "undefined" != _ele.parentNode) _ele.parentNode.removeChild(_ele);
        }
      }
      catch(e) {
      	YAHOO.bm2.BookmarksManager.debug(e,true);
      }
    },

    /*	@description	remove BM from visible list
     *  @param				(boolean) pNotWithinDDContext - optional
     * */
    removeBookmarkFromList : function(pNotWithinDDContext) {
      var _a_List = YAHOO.bm2.BookmarksManager.getCheckedBookmarkKeys();
      var _attributes = YAHOO.bm2.config.dd._dropped_drag_on_target_attributes;
      var _bookmark_id = null;
      var _downsizing = null;
      var _ele = null;
      var _c_a_List = 0;
      try {
        _c_a_List = _a_List.length;
        for (var _i=0;_i<_c_a_List;_i++) {
          _bookmark_id = _a_List[_i];
          _attributes['bId']  = _bookmark_id;
          _ele=document.getElementById(_bookmark_id);
          _downsizing = new YAHOO.util.Anim(_attributes['bId'], _attributes, _attributes['duration'],YAHOO.util.Easing.backOut);

          if (pNotWithinDDContext) {
            _downsizing.onComplete.subscribe(YAHOO.bm2.BookmarksManager.removeBookmarkFromDOM,_ele);
          }
          else {
            _downsizing.onComplete.subscribe(YAHOO.bm2.BookmarksManager.removeDDBookmarkFromDOM,_attributes);
          }
          _downsizing.animate();
        }
        YAHOO.bm2.BookmarksManager.pagination.setCountDisplay((-1 * _c_a_List));
        //YAHOO.bm2.BookmarksManager.setVisibleBookmarks(_c_a_List);
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _a_List = null;
        _attributes = null;
      }
    },

    setUncategorizedCount : function(pNumBookmarks) {
      var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_PAGE_UNCATEGORIZED_COUNT_ELEMENT.id);
      var _count = parseInt(_ele.innerHTML);
      _count += parseInt(pNumBookmarks);
      _ele.innerHTML = _count.toString();
    },

		addTagstoBookmark : function(sTags,pBookmarkId) {
			try {
				var _tmp_html = "";
  			var _s = YAHOO.bm2.BookmarksManager.doGenerateTagURL(sTags); 
		    var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_TAGS.id_prefix + pBookmarkId);
		    if (null != _ele && "undefined" != _ele) {		   
		    	_ele.innerHTML += _s;
				}
			} 
			catch(e) {
				YAHOO.bm2.BookmarksManager.debug(e,true);
			}
			finally {
				_tmp_html = null; _s = null; _ele = null;
			}
		},

    /*  @description this is retard help function that determines if the bookmarks should disappear
     *               the node does not disappear when setting the bookamrk with meta data
     * */
    isAnnotating : function() {
      var _folderId = YAHOO.bm2.config.app.current_folder_view_id;
      if (null == _folderId || "" == _folderId || "undefined" == _folderId || "all" == _folderId) {
        return true;
      }
      var _nFolderId = parseInt(_folderId);
      var _b = !(!isNaN(_nFolderId) && _nFolderId >= 0);
      return _b;
    },

    renderer : {
    	writeTagsinHTML : function(pBookmark) {
    		var _bookmark = pBookmark;
  			var _tags = _bookmark.getTags();
  			var aHtml = [];
  			for (var _t=0; _t< _tags.length; _t++) {
  				aHtml.push(this.doGenerateTagURL(_tags[_t]));
  			}
		    var sHtml = aHtml.join(', ');
		    var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_TAGS.id_prefix + pBookmark.getId());
		    if (null != _ele && "undefined" != _ele) {		   
		    	_ele.innerHTML = bm2_translations.messages['BB_BOOKMARKS_METADATA_TAGS_HEADER'] + " " + sHtml;
		    }
		    aHtml = [];
    	},
    	writeFolderInfoInHTML : function(pBookmark) {
    		var _bookmark = pBookmark;
    		var _folder_id = null; var _folder_name = null;
    		try {
			    var _ele = document.getElementById(YAHOO.bm2.config.dd.DD_FOLDERS.id_prefix + _bookmark.getId());
			    if (null != _ele && "undefined" != _ele) {
			    	_folder_id = _bookmark.getFolderId().toString();
			    	_folder_name = _bookmark.getFolderName();
			    	_ele.href = "/pages/fid/" + _folder_id;
			    	_ele.innerHTML = _folder_name;
			    }
    		}
    		catch(e) {
				  YAHOO.bm2.BookmarksManager.debug(e,true);
    		}
    	},
	    doGenerateFolderURL : function(pFolderId,pFolderName) {
	    	var _s = '<a href="/pages/fid/' + pFolderId.toString() + '">' + pFolderName + '</a>';    	
	      return _s;
	    },
	    doGenerateTagURL : function(pTag) {
	    	var _s = "";
	    	var _tag = pTag.replace('-',' ');
	    	if (null != _tag && "" != _tag) {
	    		_s = '<a href="/tags/' + _tag.toLowerCase() + '">' + _tag + '</a>';  	
	    	}
	      return _s;
	    }
    },

    executeMovetoFailure : function(pResponse) {
      YAHOO.bm2.BookmarksManager.setStateDefault();
      YAHOO.bm2.BookmarksManager.setUIMessageError();
    },

    executeMovetoSuccess : function(pResponse) {
      // this.setStateDefault();
      var _obj = pResponse.argument[0]; //get the referenced bookmark
      var _folder_id = pResponse.argument[1]; //get the folder id
			var _checked_bookmarks = YAHOO.bm2.BookmarksManager.getCheckedBookmarks();
      var _bookmark = null;
      var _folder = null;

      if (0 == parseInt(YAHOO.bm2.config.app.current_folder_view_id)) {
        YAHOO.bm2.BookmarksManager.setUncategorizedCount((-1 *_checked_bookmarks.length));
      }
      
      try {
        if (!YAHOO.bm2.BookmarksManager.isAnnotating()) {
          YAHOO.bm2.BookmarksManager.removeBookmarkFromList();
        }
        //bookmarks DO NOT disappear so the message bar must be set
        else {
          //need to set the new folder information
					try {
						var _bookmark = null;
		        for (var _key in _checked_bookmarks) {
		          if (null!=_checked_bookmarks[_key] && "undefined"!=_checked_bookmarks[_key] && ""!=_checked_bookmarks[_key]) {
							  _bookmark = _checked_bookmarks[_key];
							  _folder = YAHOO.bm2.BookmarksManager.getFolderByKey(YAHOO.bm2.config.dd.DD_TARGETABLE_USER_GENERATED_PREFIX + "-" + _folder_id);
							  _bookmark.setFolderId(_folder_id.toString());
								_bookmark.setFolderName(_folder.getTitle());							  
								YAHOO.bm2.BookmarksManager.renderer.writeFolderInfoInHTML(_bookmark);
		          }
						}
					}
					catch(e) {
						YAHOO.bm2.BookmarksManager.debug(e,true);
					}  
          var _msg = YAHOO.bm2.BookmarksManager.setUIMessage(bm2_translations.messages['MSG_SUCCESS_MOVE_TO_FOLDER'],'move');
          YAHOO.bm2.BookmarksManager.displayOverlay(true,_msg);
          setTimeout(
          	function(){ YAHOO.bm2.BookmarksManager.displayOverlay(false,null); },
          	(YAHOO.bm2.config.dd._message_timeout_duration*1000)
          );
        }
        setTimeout( //sets the height of a columns via animation
        	function() { 
        		YAHOO.bm2.BookmarksManager.setNormalizedPageHeight(null); },
      			(YAHOO.bm2.config.dd._set_normalized_page_height_attributes.magnitude * YAHOO.bm2.config.dd._set_normalized_page_height_attributes.duration * 1000)
      	);
        YAHOO.bm2.BookmarksManager.resetCheckedBookmarks();
      }
      catch (e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _checked_bookmarks = null;
        //_bookmark = null;
        _obj = null;
      }
    },

    executeAddtagsFailure : function(pResponse) {
      YAHOO.bm2.BookmarksManager.setUIMessageError();
    },

    executeAddtagsSuccess : function(pResponse){
      var _obj = pResponse.argument[0]; //get the referenced bookmark
      var _tag = pResponse.argument[1]; //get the tag
      		_tag = _tag.replace('-',' ');
      var _bookmark = null;
      			
      //YAHOO.bm2.translations.messages.MSG_SUCCESS_ADD_TAGS_TO_BOOKAMARK
      var _msg = YAHOO.bm2.BookmarksManager.setUIMessage(bm2_translations.messages['MSG_SUCCESS_ADD_TAG_TO_BOOKMARK'] + " \"" + _tag + "\"",'tag');
      YAHOO.bm2.BookmarksManager.displayOverlay(true,_msg);
			var _checked_bookmarks= YAHOO.bm2.BookmarksManager.getCheckedBookmarks();
			try {
        for (var _key in _checked_bookmarks) {
          if (null!=_checked_bookmarks[_key] && "undefined"!=_checked_bookmarks[_key] && ""!=_checked_bookmarks[_key]) {
					  _bookmark = _checked_bookmarks[_key]; 
					  if (!_bookmark.containsTag(_tag)) {
  					  _bookmark.addTag(_tag);
	  				  YAHOO.bm2.BookmarksManager.renderer.writeTagsinHTML(_bookmark);
					  }
          }
				}
			}
			catch(e) {
				YAHOO.bm2.BookmarksManager.debug(e,true);
			}
			finally{
				_checked_bookmarks = null;
				_bookmark = null;
			}
      setTimeout(
      	function(){
    			YAHOO.bm2.BookmarksManager.displayOverlay(false,null);
      	},
      	(YAHOO.bm2.config.dd._message_timeout_duration*3000)
      );      
    },
    
    execute : function(pAction,pArrayBookmarkIds,pFolderId,pArrayTags) {
      var sURL = '';
      var sBookmarkIds="";
      var sTagNames="";
      var callback = null;
      var _folder_id = pFolderId||"";
      var _form_method = "GET";
      var _obj = this;
      var _q_string  = '';
			var _tmp_array = [];
			
      if ("object" == typeof pArrayBookmarkIds) {
        var cArrayBookmarkIds = pArrayBookmarkIds.length;
        for (var _i=0;_i<cArrayBookmarkIds;_i++) {
          _tmp_array.push(encodeURIComponent("IDS[" + pArrayBookmarkIds[_i] + "]") + "=on");
        }
        sBookmarkIds = _tmp_array.join('&');
      }
      else {
        sBookmarkIds = encodeURIComponent("IDS[" + pArrayBookmarkIds + "]");
      }
      
			_tmp_array = [];
			if (null != pArrayTags && "undefined" != pArrayTags) {
	      if ("object" == typeof pArrayTags) {
	        var cArrayTags = pArrayTags.length;
	        for (var _i=0;_i<cArrayTags;_i++) {
	          _tmp_array.push("tag" + encodeURIComponent("[]") + "=" + pArrayTags[_i].replace('-',' '));
	        }
	        sTagNames = _tmp_array.join('&');
	      }
	      else {
	        sTagNames = "tag" + encodeURIComponent("[]") + "=" + encodeURIComponent(pArrayTags.replace('-',' '));
	      }
			}

      //if "frequently accessed" folder the targeted folder
      var _isFrequentlyAccessed = (_folder_id.indexOf(YAHOO.bm2.config.dd.DD_TARGETABLE_FREQ_ACCESSED_FOLDER) != -1);
			var _crumbs = YAHOO.bm2.BookmarksManager.getCrumbValue();
			
      switch (pAction.toLowerCase()) {
        case YAHOO.bm2.BookmarksManager.DD_BOOKMARKS_ACTION_ADD_TAGS :
        	sURL = '/admin/saveeditedbmmultiple';
          _q_string += sBookmarkIds //all the bookmarks
					_q_string += "&isMultipleEdits=true";
          _q_string += "&adminAction=Add";
          _q_string += "&adminEditAction=Finish";
          _q_string += (null != _crumbs) ? "&crumbs=" + _crumbs : "";
          _q_string += "&" + sTagNames; //new folder to set
					_form_method = "POST";
          callback = {
		        success: this.executeAddtagsSuccess,
		        failure: this.executeAddtagsFailure,
		        argument: [_obj,pArrayTags]
		      }
		      break;
        case YAHOO.bm2.BookmarksManager.DD_BOOKMARKS_ACTION_MOVE_TO:
          sURL = '/admin/MoveToBM';
          _q_string = "?newfid=" + _folder_id; //new folder to set
          _q_string += (_isFrequentlyAccessed) ? "&fa=1" : "";
          _q_string += "&" + sBookmarkIds; //all the bookmarks
          callback = {
		        success: this.executeMovetoSuccess,
		        failure: this.executeMovetoFailure,
		        argument: [_obj,_folder_id]
		      }
          break;
        case 'share':    sURL = '/admin/showsharebm'; break;
        case 'delete':   sURL = '/admin/deletebmconfirm'; break;
        default:         sURL = ''; break;
      }

      try {
        if (null!=sURL && ""!=sURL) {
          var oConnect = YAHOO.util.Connect;
          oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
          if ("POST" == _form_method) {
            oConnect.asyncRequest(_form_method, sURL, callback, _q_string);
          }
          else if ("GET" == _form_method) {
            oConnect.asyncRequest(_form_method, (sURL + _q_string), callback, null);
          }
          this.setStateLoading();
        }
      }
      catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        sURL = null;
        sBookmarkIds = null;
        sTagNames = null;
        _q_string  = null;
      }
   }
}

/* utility files */

YAHOO.bm2.util = {
	  
	  getSpaceId : function() {
	  	return YAHOO.bm2.config.app['current_page_space_id'];
	  },
	  
		getCookie : function(pName) {
			//TODO
		},
		setCookie : function(pName,pValue) {
			try {
	    	var nextyear = new Date();
	    	nextyear.setFullYear(nextyear.getFullYear() +1);
            
            // clear previous cookie
            var clearCookieStr = pName +'='+ pValue +'; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
            document.cookie = clearCookieStr;

            // set real cookie
	    	var _s = pName +'='+ pValue +'; path=/; domain=.bookmarks.yahoo.com; expires='+ nextyear.toGMTString();
		    document.cookie = _s;

			}
			catch(e) {
        YAHOO.bm2.BookmarksManager.debug(e,true);				
			}
		},
	  
    DDInit : function() {
      var _dd_handler = null;
      var _config = null;
      
      var _bookmarks = []; //all available bookmarks
      var _bookmark_ele = null;
      var _bookmark = null;
      var _folders = []; //all available folders
      var _folder_ele = null;
      var _folder = null;
      var _tags = [];
      var _tag_ele = null;
      var _tag = null;
      
      return {
        init : function(pCfg) {
        	YAHOO.bm2.BookmarksManager.quantify();
          try {
            if (null == pCfg || "object" != typeof pCfg) return;
            _config = pCfg;
            var _ele = null;
            
            //FEATURE: let's set the height of the left hand column
						_ele = document.getElementById(_config.dd.DD_PAGE_SEC_ELEMENT.id);
						if (null != _ele && "undefined" != _ele) {
						  YAHOO.bm2.BookmarksManager.ONLOAD_SECONDARY_COLUMN_HEIGHT = parseInt(_ele.offsetHeight);
						}
						
            //FEATURE: let's set up error handling / display
            //         only for non-IE browsers
            YAHOO.bm2.BookmarksManager._IS_DEBUG = _config._IS_DEBUG;
            if (_config._IS_DEBUG && !YAHOO.bm2.config.dd.isIE) {
               try {
                 _ele = document.createElement(YAHOO.bm2.config.dd.DD_BB_DEBUG_LOG_ELEMENT.type);
                 _ele.setAttribute("id", _config.dd.DD_BB_DEBUG_LOG_ELEMENT.id);
                 document.body.appendChild(_ele);
                 _ele.style.visibility = "visible";
                 _ele.style.display = "block";
               }
               catch(e) {
                 //TODO:handle exception
                 YAHOO.bm2.BookmarksManager.debug(e,true);
               }
               finally {
                 _ele = null;
               }
            }

            //FEATURE: let's set up the hidden scroll handler
            if (_config.dd.feature.hiddenScrollHandler._IS_ENABLED) {
              _ele = document.getElementById(_config.dd.feature.hiddenScrollHandler.id);
              if (null != _ele && "undefined" != _ele) {
                YAHOO.util.Event.addListener(_ele, "mouseover", function() { YAHOO.bm2.BookmarksManager.startScroll(); });
                YAHOO.util.Event.addListener(_ele, "mouseout", function() { YAHOO.bm2.BookmarksManager.endScroll(); });
              }
            }

            _dd_handler = YAHOO.util.DDM;
            _dd_handler.mode = YAHOO.util.DDM.POINT;

            // _folders / targets           
            var _dd_folder = YAHOO.bm2.util.DDBookmarkTarget;
            var _dd_folder_children = YAHOO.util.Dom.getElementsByClassName(
                    _config.dd.DD_TARGETABLE_ELEMENT.className,
                    _config.dd.DD_TARGETABLE_ELEMENT.type,
                    YAHOO.util.Dom.get(_config.dd.DD_FOLDERS_CONTAINER.id));
            
            var _dd_tag = YAHOO.bm2.util.DDBookmarkTarget;
            var _dd_tag_children = YAHOO.util.Dom.getElementsBy(
                    function() { return true; },
                    _config.dd.DD_TAGS.type,
                    YAHOO.util.Dom.get(_config.dd.DD_TAGS_CONTAINER.id));
                    
            var _id = null;
            var _attributes = [];

      			var _title_ele = null;
      			var _title = "";
      
						//targetable folders
            var _count_dd_folder_children = _dd_folder_children.length;
            if (_count_dd_folder_children > 0) {
              for (var _i=0;_i < _count_dd_folder_children;_i++) {
                _id = _dd_folder_children[_i].id;
                _title = _dd_folder_children[_i].firstChild.firstChild.nodeValue.replace(" ","-");
                _attributes['id'] = _id;
                _attributes['title'] = _title;
                _folders[_id] = new _dd_folder(_id, _config.dd.DD_BOOKMARKS_FOLDER_LIST_KEY.key,_attributes);
              }
              YAHOO.bm2.BookmarksManager.setFolders(_folders);
            }
						//targetable tags
						_attributes = [];
						try {
	            var _count_dd_tag_children = _dd_tag_children.length;
	            if (_count_dd_tag_children > 0) {
	              for (var _i=0;_i < _count_dd_tag_children;_i++) {
	                //_id = _dd_tag_children[_i].id;
	                _title = _dd_tag_children[_i].firstChild.nodeValue.replace(' ','-').replace('+','-');
	                _attributes['title'] = _title;
	                _tag = new _dd_tag(_config.dd.DD_TAGS.id_prefix + _title.toLowerCase(), _config.dd.DD_BOOKMARKS_TAGS_LIST_KEY.key,_attributes);
	                _tags.push(_tag);
	              }
	              YAHOO.bm2.BookmarksManager.setTags(_tags);
	            }
						}
						catch(e){	
							YAHOO.bm2.BookmarksManager.debug(e,true);
						}
            
            // bookmarks: only enable drag and drop if there are targetable folders
            if (_count_dd_folder_children > 0) {
              var _dd_bookmark = YAHOO.bm2.util.DDBookmark;
              var _root_bookmarks_ele = YAHOO.util.Dom.get(_config.dd.DD_BOOKMARKS_CONTAINER.id);
              var _dd_bookmark_children = YAHOO.util.Dom.getElementsByClassName(
                        _config.dd.DD_BOOKMARKS_ELEMENT.className,
                        _config.dd.DD_BOOKMARKS_ELEMENT.type,
                        _root_bookmarks_ele);
              try {
                if (_dd_bookmark_children.length > 0) {
                  _tags = [];
                  var _count_dd_bookmarks_children = _dd_bookmark_children.length;
                  var _key = null;
                  for (var _i=0;_i < _count_dd_bookmarks_children;_i++) {
                  	try {
	                    _key = _dd_bookmark_children[_i].id;
	                    _title_ele = YAHOO.util.Dom.getElementsByClassName(
	                              _config.dd.DD_BOOKMARKS_TITLE.className,
	                              _config.dd.DD_BOOKMARKS_TITLE.type,
	                              _dd_bookmark_children[_i]);
	                    _title = _title_ele[0].innerHTML;
	                    //set folder information for this bookmark
											var _bookmark_folder = [];
	                    _folder_ele = document.getElementById(_config.dd.DD_FOLDERS.id_prefix + _key);
	                    if (null != _folder_ele && "undefined" != _folder_ele && "A" == _folder_ele.tagName) {
	                    	//_bookmark_folder['id'] = YAHOO.bm2.BookmarksManager.getQueryStringValue('FID',_folder_ele.href);
	                    	_bookmark_folder['id'] = parseInt(_folder_ele.href);
	                    	_bookmark_folder['name'] = _folder_ele.innerHTML;
	                    }
	                    //set tags information for this bookmark
	                    var _tags_container = document.getElementById(_config.dd.DD_TAGS.id_prefix + _key);
	                    if (null != _tags_container && "undefined" != _tags_container) {
			                    var _tmp_tags = _tags_container.getElementsByTagName('A');
	    		                for (var _t=0; _t < _tmp_tags.length; _t++) {
	            		        	_tags.push(_tmp_tags[_t].innerHTML.toString());
	                		    }
	                    }
	                    _bookmark = new _dd_bookmark(_key, _config.dd.DD_BOOKMARKS_FOLDER_LIST_KEY.key);
	                    _bookmark.initBookmark(_key, _config.dd.DD_BOOKMARKS_FOLDER_LIST_KEY.key);
	                    _bookmark.addToGroup(_config.dd.DD_BOOKMARKS_TAGS_LIST_KEY.key);
	                    _bookmark.setTitle(_title);
	                    _bookmark.setTags(_tags);
	                    _bookmark.setFolder(_bookmark_folder);
	                    _bookmarks[_key] = _bookmark;
                  	}
                  	catch(e) {
                  		YAHOO.bm2.BookmarksManager.debug(e,true);
                  	}
                  	finally {
                  		_title = "";
                  		_tags = [];
                  	}
                  }
                  YAHOO.bm2.BookmarksManager.setBookmarks(_bookmarks);
                }
              }
              catch(e) {
                YAHOO.bm2.BookmarksManager.debug(e,true);
              }
              finally {
                _root_bookmarks_ele = null;
                _bookmark = null;
                _dd_bookmark = null;
                _dd_bookmark_children = null;
                _key = null;
              }
            }
          }
          catch (e) {
            YAHOO.bm2.BookmarksManager.debug(e,true);
          }
          finally {
            _dd_folder = null;
            _dd_folder_children = null;
            //_folders = null;
            //_bookmarks = null;
            _title_ele = null;
            _title = null;
          }
          if (YAHOO.bm2.config.dd.isIE) YAHOO.bm2.BookmarksManager.setCursor(document.body,'default');
          //YAHOO.util.Event.addListener(window, "load", function() { YAHOO.bm2.BookmarksManager.doCaptureKeystrokeInit(); });
        }
      };
    }(),
	  
    /*    @object DD target
     * */
    DDBookmarkTarget : function(pId, sGroup, config) {
      if (pId) {
        if (config) this.title = config['title'];
        this.TYPE = YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.object_type;
        this.initTarget(pId, sGroup, config);
      }
      this.getTitle = function() { return this.title; }
      this.onDragOver = function(e, id) { }
    },

    /*    @object DD bookmark
     * */
    DDBookmark : function(id, sGroup, config) {
      this.initBookmark = function(id, sGroup) {
        if (!id) { return; }
        this.TYPE = YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.object_type;
        
        this.init(id, sGroup, config); //super()
        this.initFrame(); //super()
        
        this.isTarget = false; //is this element a target? NO!
        
        this.title = null;
				this.folderId = -1;
				this.folderName = null;
			  this.tags = [];
			  this.url = "";

        this.scroll = false; //this let's the DDManager know whether to scroll
        this.originalStyles = [];//TODO:deprecated

        this.EVENT_TYPE_GRAB = "drag";
        this.EVENT_TYPE_DRAGGING = "dragging";
        this.EVENT_TYPE_DEFAULT = "default";

				for (var _i=0; _i  <YAHOO.bm2.config.dd.DD_CLASSNAMES_OF_UNDRAGGABLE_ELEMENTS.length; _i++) {
					this.addInvalidHandleClass(YAHOO.bm2.config.dd.DD_CLASSNAMES_OF_UNDRAGGABLE_ELEMENTS[_i]);
				}
				
        var _bookmark_container = document.getElementById(id);
        this.bookmarkId = _bookmark_container.id;
        
        /*
        if (null != _bookmark_container && "undefined"!=_bookmark_container) {
            YAHOO.bm2.BookmarksManager.setCursor(_bookmark_container.childNodes[1],this.EVENT_TYPE_GRAB);
            YAHOO.bm2.BookmarksManager.setCursor(_bookmark_container.childNodes[3],this.EVENT_TYPE_GRAB);
        }
        */
        YAHOO.bm2.BookmarksManager.setCursor(_bookmark_container,this.EVENT_TYPE_GRAB);
        this.setOpacity(this.getDragEl(),YAHOO.bm2.config.dd.transluscentBookmark);
      }

      //should be DEPRECATED
      this.$ = function(pName) { return document.getElementById(pName); }
      
      this.getId = function() { return this.id; }
      this.setId = function(pId) { this.id = pId; }
      this.getTitle = function() { return this.title; }
      this.setTitle = function(pTitle) { this.title = pTitle; }
      this.getFolder = function() { return this.folder; }
      this.setFolder = function(pFolder) { if (null != pFolder) this.folder = pFolder; }
      this.getFolderId = function() { return this.folder['id']; }
      this.setFolderId = function(pFolderId) { if ("" != pFolderId) this.folder['id'] = pFolderId; }
      this.getFolderName = function() { return this.folder['name']; }
      this.setFolderName = function(pFolderName) { if ("" != pFolderName) this.folder['name'] = pFolderName; }
      this.getUrl = function() { return this.url; }
      this.setUrl = function(pUrl) { this.url = pUrl; }
      this.getTags = function() { return this.tags; }
      this.setTags = function(pTags) { this.tags = pTags; }
      this.addTag = function(pTag) { this.tags.push(pTag); }
			this.removeTag = function(pTag) { /*TODO */ }
			this.containsTag = function(pTag) { 
				var _tags = this.getTags();
				for (var _t=0; _t < _tags.length; _t++) {
					if (pTag == _tags[_t]) return true;
				}	
				return false;
			}

      this.getTargetDomRef = function(oDD) { var _e = (oDD.bookmark) ? oDD.bookmark.getEl() : oDD.getEl(); return _e; }
      this.getTargets = function() { return YAHOO.util.DDM.getRelated(this, true); }

      this.setOpacity = function(pEle,pNum) {	YAHOO.bm2.BookmarksManager.setOpacity(pEle,pNum); }
      this.setCursor = function(pEle,pVal) { YAHOO.bm2.BookmarksManager.setCursor(pEle,pVal); }
      this.setBGColor = function(pEle,pColor) { if (pEle && pEle.style) pEle.style.backgroundColor = pColor; }

      this.onMouseDown = function(e) {}

      /*    @return (void) called when dragging inits
       * */
      this.startDrag = function(x,y) {
                
       	YAHOO.bm2.BookmarksManager.setIsDragging(true);
        var dragEl = this.getDragEl(); //absolutely positioned proxy element
        var clickEl = this.getEl(); //the handle that is being grabbed
       	
       	//FEATURE:enable the scroll layer if necc
        if (YAHOO.bm2.config.dd.feature.hiddenScrollHandler._IS_ENABLED) {
          YAHOO.bm2.BookmarksManager.setVisibilityScrollLayer(true);
        }

        //tell inlines action to stop!!!
        var _mgr = YAHOO.bm2.BookmarksManager.getInlineActionsManager();
        try { _mgr.reset();
        } catch(e) { YAHOO.bm2.BookmarksManager.debug(e,true);
        } finally { _mgr = null; }

      	//any checked bookmarks need love too
        var _checked_bookmarks = YAHOO.bm2.BookmarksManager.parseCheckedBookmarks(clickEl.id);
        if (null!= _checked_bookmarks && "undefined" != _checked_bookmarks) {
          YAHOO.bm2.BookmarksManager.setCheckedBookmarks(_checked_bookmarks);
        }
        var _c_checked_bookmarks = _checked_bookmarks.length;
        var _tmp_html = clickEl.innerHTML;
        
        try { 
          if (_c_checked_bookmarks > 0) {
            _tmp_html += '<' + YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS.type + ' class="' + YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS.className + '">';
            for (var _i=0; _i<_c_checked_bookmarks;_i++) {
              _tmp_html += "<"+ YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS_ITEM.type + " class=\"" + ((0==_i) ? "first" : "") + "\">";
              _tmp_html += _checked_bookmarks[_i].title;
              _tmp_html += "</"+ YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS_ITEM.type + ">";
              YAHOO.bm2.BookmarksManager.setOpacity(this.$(_checked_bookmarks[_i].id),YAHOO.bm2.config.dd.transluscentProxyElement);
              //YAHOO.bm2.BookmarksManager.debug("mark Id: " +_checked_bookmarks[_i].id);
            }
            _tmp_html += '</' + YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT_ADDL_BMS.type + '>';
          }

	        //let's duplicate like a chameleon
	        //this is the proxy element that is dragged around
	        dragEl.innerHTML = _tmp_html;
	        dragEl.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT.className;
	        dragEl.style.position ="absolute";
	        dragEl.style.width = YAHOO.bm2.config.dd._proxy_element_attributes.width.value + YAHOO.bm2.config.dd._proxy_element_attributes.width.unit;
	        dragEl.style.height = YAHOO.bm2.config.dd._proxy_element_attributes.height.value + YAHOO.bm2.config.dd._proxy_element_attributes.height.unit;
	        dragEl.style.fontSize = YAHOO.bm2.config.dd._proxy_element_attributes.font.value + YAHOO.bm2.config.dd._proxy_element_attributes.font.unit;
	        dragEl.style.left = x + "px";
	        dragEl.style.top = y + "px";
	        dragEl.style.zIndex = 1701;
	        this.setDelta(-5,-15);
	
	        //let's shrink-wrap the proxy element w/ YUI animation
	        var _tmp_height = -1;
	        var _attributes = YAHOO.bm2.config.dd._start_drag_attributes;
	        if (_c_checked_bookmarks > 0) {
	          _tmp_height = _attributes.height.to;
	          _attributes.height.to = (_c_checked_bookmarks * (_attributes.height.to + YAHOO.bm2.config.dd.offset_height_proxy_element));
	        }
	        var _downsizing = new YAHOO.util.Anim(dragEl, _attributes,
	                                                  YAHOO.bm2.config.dd._start_drag_attributes.duration,
	                                                  YAHOO.util.Easing.easeBoth);
          _downsizing.animate();

          if (-1 != _tmp_height) _attributes.height.to = _tmp_height; //reset this value: dumb HACK

          YAHOO.bm2.BookmarksManager.setOpacity(clickEl,YAHOO.bm2.config.dd.transluscentProxyElement);
          YAHOO.bm2.BookmarksManager.setCursor(null,this.EVENT_TYPE_DRAGGING);

					//FEATURE: enable the moving folder list
          if (YAHOO.bm2.config.dd.feature.movingFolderTreeList._IS_ENABLED) {
            YAHOO.bm2.BookmarksManager.doMoveFoldersTreeList(true,this); //let's move the folder list
          }
        }
        catch(e) {
          //TODO:catch exception
        }
        finally {
          dragEl = null;
          handleClickEl = null;
          clickEl = null;
          _downsizing = null;
          _checked_bookmarks = null;
        }
      }

      /*    @return (void) called when dragging ends
       * */
      this.endDrag = function(e) {
        var _bookmark = this.getEl();
        var _bookmark_container = _bookmark;
        try {
        	YAHOO.bm2.BookmarksManager.setIsDragging(false);
          this.resetCursor();
          this.resetBookmarks();
          // this.resetTargets();

          var _self = this;
          if (YAHOO.bm2.config.dd.feature.movingFolderTreeList._IS_ENABLED) {
              YAHOO.bm2.BookmarksManager.doMoveFoldersTreeList(false,_self); //let's reset the folder list
          }
          YAHOO.util.Dom.setXY(this.getDragEl(),YAHOO.bm2.config.dd.posDormantProxyElement); //set the proxy element away from visible viewport
        }
        catch(e) {
          //TODO:handle exception
          YAHOO.bm2.BookmarksManager.debug(e,true);
        }
        finally {
          _bookmark = null;
          _bookmark_container = null;
        }
        //FEATURE: disable the scroll feature if enabled
        if (YAHOO.bm2.config.dd.feature.hiddenScrollHandler._IS_ENABLED) {
          YAHOO.bm2.BookmarksManager.endScroll();
          YAHOO.bm2.BookmarksManager.setVisibilityScrollLayer(false,this);
        }
        return false;
      }

      this.resetTargets = function() {
        var targets = this.getTargets();
        var oldStyle = null;
        var targetEl = null;
        try {
          if (null != targets && "undefined" != targets) {
            for (var i=0; i<targets.length; i++) {
              targetEl = this.getTargetDomRef(targets[i]);
              if (null != targetEl && "undefined" != targetEl) {
                oldStyle = this.originalStyles[targetEl.id];
                if (oldStyle) targetEl.className = oldStyle;
              }
            }
          }
        }
        catch(e) {
          YAHOO.bm2.BookmarksManager.debug(e,true);
        }
        finally {
          targets = null;
          oldStyle = null;
          targetEl = null;
        }
      }

      this.resetBookmarks = function() {
        var _bookmarks = YAHOO.bm2.BookmarksManager.getBookmarks();
        var _ele = null;
        var _isEnteringHiddenBookmarks = false; //TODO: what in the hell is this?
        try {
          for (var key in _bookmarks) {
            if (_isEnteringHiddenBookmarks) break;
            if (null!=_bookmarks[key] && "undefined"!=_bookmarks[key] && ""!=_bookmarks[key]) {
              _ele = this.$(key);
              YAHOO.bm2.BookmarksManager.setOpacity(_ele,1);
              if (null!=_ele && "undefined"!=_ele &&
                _ele.className.indexOf(YAHOO.bm2.config.dd.DD_BOOKMARKS_ELEMENT.hiddenClassName) != -1) {
                _isEnteringHiddenBookmarks = true;
              }
            }
	        }
        }
        catch(e) {
          YAHOO.bm2.BookmarksManager.debug(e,true);
        }
        finally {
          _bookmarks = null;
          _ele = null;
        }
      }

    this.resetCursor = function() {
      YAHOO.bm2.BookmarksManager.setCursor(null,this.EVENT_TYPE_DEFAULT);
    }

    /*    @return (void) called when mouse releases DD proxy
     * */
    this.onDragDrop = function(e, pId) {
      // this condition, if user drops a bookmark over a red target
      if (pId.indexOf(YAHOO.bm2.config.dd.DD_TARGETABLE_STATIC_PREFIX) != -1) {
        //TODO:anything to do?
      }
      else {
        this.onDragOut(e,pId);//let's call it to set visual cues
        //this.lock();

        var _bookmark = this.getEl();
        var _bookmark_container = _bookmark; // should be _bookmark.parentNode
	      var _a_List = []; //to be an array of checked bookmarks

				// if dropping the bookmark on the TAG
        if (pId.indexOf(YAHOO.bm2.config.dd.DD_TAGS.id_prefix) != -1) {
	          var _tag = pId.substring(YAHOO.bm2.config.dd.DD_TAGS.id_prefix.length);
 						_a_List = YAHOO.bm2.BookmarksManager.getCheckedBookmarkKeys();
	          //YAHOO.bm2.BookmarksManager.debug("tag name: " + _tag);
	          YAHOO.bm2.BookmarksManager.execute(YAHOO.bm2.BookmarksManager.DD_BOOKMARKS_ACTION_ADD_TAGS, _a_List, null, _tag);      
        }
        // if dropping the bookmark on the FOLDER
        else {
	        var _target_folder = null;
	        var _target_folder_id = "";
	
	        // if accessing the Frequently Accessed Folder
	        if (pId.indexOf(YAHOO.bm2.config.dd.DD_TARGETABLE_FREQ_ACCESSED_FOLDER) != -1) {
	          _target_folder_id = pId;
	        }
	        else {
	          _target_folder = this.$(pId);
	          _target_folder_id = _target_folder.id.substring((YAHOO.bm2.config.dd.DD_BB_PARENT_FOLDERS_LIST_ID.length - 1));
	        }
	        if (parseInt(YAHOO.bm2.config.app.current_folder_view_id) == _target_folder_id) {
	          // DO NOTHING: user has dropped the bookmark on the currently viewed folder
	        }
	        else {
	          try {
	            // get the drag and drop object that was targeted
	            //var oDD = ("string" == typeof pId) ? YAHOO.util.DDM.getDDById(pId) : YAHOO.util.DDM.getBestMatch(pId);
	            _a_List = YAHOO.bm2.BookmarksManager.getCheckedBookmarkKeys();
	            YAHOO.bm2.BookmarksManager.execute(YAHOO.bm2.BookmarksManager.DD_BOOKMARKS_ACTION_MOVE_TO, _a_List, _target_folder_id, null);
	            this.resetTargets();
	          }
	          catch (e) {
	            YAHOO.bm2.BookmarksManager.debug(e,true);
	          }
	          finally {
	            //reset local vars
	            _bookmark = null;
	            _bookmark_container = null;
	            oDD = null;
	            _target_folder = null;
	            _target_folder_id = null;
	            //_a_List = null;
	          }
	        }
        }
        //this.unlock();
      }
    }

    /*    @return (void) called whenever DD proxy is moved over a "targetable" element
     * */
    this.onDragOver = function(e, pId) {
      var _e_proxy = this.getDragEl();
      var _e_targetable = this.$(pId);

      try {
        if (YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.type == _e_targetable.tagName.toUpperCase() &&
          pId.indexOf(YAHOO.bm2.config.dd.DD_TARGETABLE_STATIC_PREFIX) != -1) {
          _e_proxy.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT.className + " " + YAHOO.bm2.config.dd.DD_NONTARGETABLE_ELEMENT.className;
        }
        else { // set targetable item, inviting drop action
          _e_proxy.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT.className + " " + YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.className;
          this.setBGColor(_e_targetable,YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.activeBgColor);
        }
        YAHOO.bm2.BookmarksManager.setCursor(null,this.EVENT_TYPE_DEFAULT);
      }
      catch(e) {
        //TODO:handle exception
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _e_proxy = null;
        _e_targetable = null;
      }
    }

    /*    @return (void) called whenever a DD proxy is moved away from a "targetable" element
     * */
    this.onDragOut = function(e, pId) {
      var _e_proxy = this.getDragEl();
      var _e_targetable = this.$(pId);
      try {
        if (YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.type == _e_targetable.tagName.toUpperCase() &&
          pId.indexOf(YAHOO.bm2.config.dd.DD_TARGETABLE_STATIC_PREFIX) != -1) {
          _e_proxy.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT.className;
        }
        else { // reset targetable item
          _e_proxy.className = YAHOO.bm2.config.dd.DD_BOOKMARKS_PROXY_ELEMENT.className;
          this.setBGColor(_e_targetable,YAHOO.bm2.config.dd.DD_TARGETABLE_ELEMENT.inactiveBgColor);
        }
        YAHOO.bm2.BookmarksManager.setCursor(null,this.EVENT_TYPE_DRAGGING);
      }
      catch(e) {
        //TODO: catch exception
        YAHOO.bm2.BookmarksManager.debug(e,true);
      }
      finally {
        _e_proxy = null;
        _e_targetable = null;
      }
    }

    /*    @return (void) called when DD proxy is being moved via onmousemove
     * */
    this.onDrag = function(e, pId) {
    }
  }
}
YAHOO.extend(YAHOO.bm2.util.DDBookmarkTarget, YAHOO.util.DDTarget);
YAHOO.extend(YAHOO.bm2.util.DDBookmark,       YAHOO.util.DDProxy);
//YAHOO.util.Event.addListener(window, "load", function() { YAHOO.bm2.BookmarksManager.init(YAHOO.bm2.config) });

// buffer object in global space
YAHOO.bm2.bmBuffer = {"totalcount":0,"results":[]};


/* BUFFER MANAGEMENT */
// initalize object
YAHOO.bm2.buffer = function(psFID, psPageOffset) {
   this.sFID = psFID;
   this.sPageOffset = (psPageOffset && psPageOffset>=1) ? psPageOffset : 1;
   this.isFetchingData = false;
   this.isActivelyWaiting = false;
   this.visibleCount = 20;
}


/* manages totalcount */
// returns totalcount from buffer
YAHOO.bm2.buffer.prototype.getTotalCount = function() {
    return YAHOO.bm2.bmBuffer.totalcount;
}
// this adds to the total count of bookmarks
YAHOO.bm2.buffer.prototype.addTotalCount = function(piNumToAdd) {
//console.log('addTotalCount()');
    var iNumToAdd = (!piNumToAdd) ? 1 : piNumToAdd;
    YAHOO.bm2.bmBuffer.totalcount = YAHOO.bm2.bmBuffer.totalcount + iNumToAdd;
}
// this removes from the total count of bookmarks
YAHOO.bm2.buffer.prototype.subTotalCount = function(piNumToSub) {
    if (!piNumToSub) return;
    YAHOO.bm2.bmBuffer.totalcount = YAHOO.bm2.bmBuffer.totalcount - piNumToSub;
}


/* get/remove stuff from buffer */
// adds an object to buffer
YAHOO.bm2.buffer.prototype.addToBuffer = function(paResults) {
    //console.log('buffer - addToBuffer: '+ paResults);
    if (!paResults.length > 0) return;
    // add object to buffer
    this.topUpBuffer(paResults, 'start');
    // add to totalcount
    this.addTotalCount(paResults.length);
}
// keeps track of how many Bookmarks are currently in this folder
YAHOO.bm2.buffer.prototype.countBuffer = function() {
    return YAHOO.bm2.bmBuffer.results.length;
}
// returns totalcount from buffer
YAHOO.bm2.buffer.prototype.getFromBuffer = function(piNumToGet) {
    //console.log('buffer - getFromBuffer('+piNumToGet+')');
    // if what you want is less or equal to what we have, return it
    if (piNumToGet <= this.countBuffer()) {
        return YAHOO.bm2.bmBuffer.results.slice(0, piNumToGet);
    }
    // otherwise, just return what you can
    return YAHOO.bm2.bmBuffer.results.slice(0);
}
// remove from buffer
YAHOO.bm2.buffer.prototype.removeFromBuffer = function(piIndex) {
    // remove from the buffer
    for (var i=0; i<piIndex; i++) {
        YAHOO.bm2.bmBuffer.results.shift();
    }
    // re-calc total
    this.subTotalCount(piIndex);
}
// return buffer data for display
YAHOO.bm2.buffer.prototype.useBufferData = function(piNumToGet) {
    //console.log('buffer - useBufferData('+piNumToGet+')');
    // only return data if we NEED to
    if (this.countBuffer()>0) {
        //console.log('buffer - getting data from buffer - because it has ('+this.countBuffer()+') to give');
        // return data instantly if we have enough in the buffer
        if (piNumToGet <= this.countBuffer()) {
            //console.log('buffer - ENOUGH IN BUFFER, YAY!');
            var aDataToReturn = [];
            // get buffer items, and then remove 'em from buffer
            aDataToReturn = this.getFromBuffer(piNumToGet);
            this.removeFromBuffer(piNumToGet);
            // go top up the buffer
            this.fetchMoreData(piNumToGet);
            // return this data
            return aDataToReturn;
        } else {
            //console.log('buffer - NOT ENOUGH DATA IN BUFFER, MUST GET MORE BEFORE WE CAN USE IT');
            this.isActivelyWaiting = true;
            this.fetchMoreData(piNumToGet);
            return 'fetching';
        }
    } else {
        //console.log('failed');
    }
}


/* fetch more buffer data from the server */
// make a call to remote server to get more data
YAHOO.bm2.buffer.prototype.fetchMoreData = function(piNumToGet) {
    // don't perform if we don't need it
    if (this.getTotalCount <= this.visibleCount) return;
    // calculate how much data we need
    var iNumToGet = this.visibleCount - this.countBuffer();
    // calculate offset (which bookmark to start with)
    // (number per page * pageOffset) - number we just got rid of + number currently in buffer
    var iOffset =  ((this.visibleCount * this.sPageOffset) - piNumToGet) + this.visibleCount;
    //console.log('buffer - offset (('+this.visibleCount+' * '+this.sPageOffset+') - '+piNumToGet+') + '+this.countBuffer());
    //console.log('buffer - fetching ('+iNumToGet+') from database to top-up buffer at offset ('+iOffset+')');
    // assign callback functions
    var callback = {
        success: this.fetchDataSuccess,
        failure: this.fetchDataFail,
        argument: [this]
    }
    // make the connection, add custom header for Symfony support
    var oConnect = YAHOO.util.Connect;
    var sURL = '/admin/jsonresults?count='+ iNumToGet +'&b='+ iOffset +'&FID='+ this.sFID;
    oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
    oConnect.asyncRequest('GET', sURL, callback, null);
    // set flags
    this.isFetchingData = true;
}
YAHOO.bm2.buffer.prototype.fetchDataFail = function(o) {
    //console.log('buffer - Ajax fetch FAILED');
    // remove flags
    this.isFetchingData = false;
    this.isActivelyWaiting = false;
    // get this object, put in obj
    var obj = o.argument[0];
    // set flags
    this.isFetchingData = false;
}
YAHOO.bm2.buffer.prototype.fetchDataSuccess = function(o) {
    //console.log('buffer - Ajax fetch SUCCESS');
    // remove flags
    this.isFetchingData = false;
    this.isActivelyWaiting = false;
    // get this object, put in obj
    var obj = o.argument[0];
    // get results into array
    var aResponseText = o.responseText.split('<!--');
    var sResponseText = aResponseText[0]
    var aResults = eval(sResponseText);
    // fill buffer
    obj.topUpBuffer(aResults, 'end');
}
// adds newly fetched items to buffer
YAHOO.bm2.buffer.prototype.topUpBuffer = function(paData, psPosition) {
    //console.log('topping up buffer now with ('+ paData.length +') new items');
    // add data to buffer
    for (var i=0; i<paData.length; i++) {
        //console.log(paData[i].TITLE);
        if (psPosition && psPosition=='start') {
            YAHOO.bm2.bmBuffer.results.unshift(paData[i]);
        } else {
            YAHOO.bm2.bmBuffer.results.push(paData[i]);
        }
    }
}


// print out buffer contents
YAHOO.bm2.buffer.prototype.log = function() {
    // print out messages
    //console.log('buffer - we now have ('+ this.getTotalCount() +') bookmarks in this folder');
    //console.log('buffer - we now have '+ this.countBuffer() +' total pages in buffer');
    for (i=0; i<this.countBuffer(); i++) {
       //console.log('buffer - item '+ i +' - '+YAHOO.bm2.bmBuffer.results[i].TITLE); 
    }
}/* BOOKMARK LIST MANAGEMENT */
YAHOO.bm2.bookmarkList = function(psFID, psPageOffset) {
    this.sIdPrefix = 'selectBM';           // prefix on IDs of checkboxes
    this.sPageOffset = psPageOffset;       // which page we're currently on
    this.sFID = psFID;                     // id of folder we are in
    this.sFormId = 'actionsform';          // id of action form
    this.sBookmarkListId = 'visiblebms';   // id of entire list of bookmarks
    this.sNoBookmarksId = 'noresults';     // id of object we display when there are no bookmarks
    this.aCheckBoxes = false;              // array of checkboxes
    this.sInfoEndId = 'infoend';           // id of infoBar end number
    this.sInfoStartId = 'infostart';       // id of infoBar start number
    this.sInfoTotalId = 'infototal';       // id of infoBar total bookmarks
    this.iBookmarkListSize = 20;           // how many bookmarks can be in list
    this.sFormData = '';                   // string of form data, created by external object (inlineActions?)
    this.oBuffer = new YAHOO.bm2.buffer(psFID, psPageOffset);  // buffer obj, use if you need to backfill
}
// returns array of checkboxes
YAHOO.bm2.bookmarkList.prototype.getCheckBoxes = function() {
    this.aCheckBoxes = YAHOO.util.Dom.getElementsByClassName('chkbx', 'input', this.sBookmarkListId);
    return this.aCheckBoxes;
}


/* DELETES/MOVES BOOKMARKS OUT OF LIST */
// check if this is an "all" folder, if not, remove all checked BMs from list
YAHOO.bm2.bookmarkList.prototype.actionMoveBookmarks = function(psFormData) {
    // update the bookmark, if bookmarks on 'all' page
    if (this.sFID=='all') {
        // get form data
        var oFormData = this.compileFormData(psFormData);
        // get nodes we need
        var aCheckboxes = this.getCheckBoxes();
        var aNodes = [];
        var tmpID;
        for (var i=0; i<aCheckboxes.length; i++) {
            if (aCheckboxes[i].checked) {
                tmpID = aCheckboxes[i].id.substr(8);
                aNodes.push(document.getElementById(tmpID));
            }
        }
        // get folder and change it
        var oFolder;
        for (i=0; i<aNodes.length; i++) {
            oFolder = document.getElementById('bb-folder-'+aNodes[i].id);
            if (oFolder && oFormData['NEWFOLDERNAME']) {
                oFolder.innerHTML = oFormData['NEWFOLDERNAME'];
                oFolder.href = '/pages/fid/'+ oFormData['NEWFID'];
            }
        }
        // get messages
        var aMessages, oMessage, aClr, aParent;
        for (i=0; i<aNodes.length; i++) {
            // remove any previous messages and add new ones
            aMessages = YAHOO.util.Dom.getElementsByClassName('displaymsg', '', aNodes[i]);
            for (ii=0; ii<aMessages.length; ii++)  {
                aMessages[ii].parentNode.removeChild(aMessages[ii]);
            }
            // add new message
            oMessage = document.createElement('div');
            oMessage.className = 'displaymsg';
            oMessage.innerHTML = '<span>' +bm2_translations.messages.MSG_ACTIONMSG_PREFIX +' </span>'+ bm2_translations.messages.MSG_ACTIONMSG_MOVED; 
            // insert new message before clear element
            aClr = YAHOO.util.Dom.getElementsByClassName('clr', 'div', aNodes[i]);
            if (aClr[0]) {
                oParent = aClr[0].parentNode;
                oMsg = oParent.insertBefore(oMessage, aClr[0]);
            }
        }
        return;
    } else {
        // remove bookmark, if not on 'all' page
        this.actionRemoveBookmarks();
    }
}
// crawls the bookmark list, removing any checked bookmarks
YAHOO.bm2.bookmarkList.prototype.actionRemoveBookmarks = function() {
    this.aCheckBoxes = this.getCheckBoxes();
    if (!this.aCheckBoxes.length>0) return;
    // loop through bookmarks looking for checked input boxes
    var counter = 0;
    var iLength = (this.aCheckBoxes.length > 20) ? 20 : this.aCheckBoxes.length;
    for (var i=0; i<iLength; i++) {
        if (this.aCheckBoxes[i].checked) {
            // remove any prefix
            var sIdToRemove = this.aCheckBoxes[i].id.substr(this.sIdPrefix.length);
            // remove bookmark from list
            this.removeBookmark(sIdToRemove);
            // update counter
            counter--;
        }
    }
    // update infoBar
    this.updateInfoBar(counter);
}
// removes the last bookmark from the list
YAHOO.bm2.bookmarkList.prototype.actionRemoveLastBookmark = function() {
    // get handle of visible bookmarks list
    var aBookmarks = this.getCheckBoxes();
    // check to make sure there are 20 items in the list, and if so: remove last item
    if (aBookmarks && (aBookmarks.length >= this.iBookmarkListSize) ) {
        // remove any prefixe
        var sLastId = aBookmarks[aBookmarks.length-1].id.substr(this.sIdPrefix.length);
        // put object into buffer
        this.saveNodeToBuffer(sLastId);
        // remove bookmark from list
        this.removeBookmark(sLastId);
    }
}
YAHOO.bm2.bookmarkList.prototype.saveNodeToBuffer = function(psLastId) {
    // get reference to this node
    var oThisNode = document.getElementById(psLastId);
    // extract node data
    var oNode = this.getNode();
    var oNodeData = oNode.extractNodeData(oThisNode);
    var aData = [oNodeData];
    // add to buffer
    this.oBuffer.addToBuffer(aData);
}
YAHOO.bm2.bookmarkList.prototype.removeBookmark = function(psIdToRemove) {
    if (!psIdToRemove) return;
    // get reference to whole bookmark object, based on value of checkbox id
    var oBookmark = document.getElementById(psIdToRemove)
    // remove element
    if (!oBookmark) return;
    var oParent = oBookmark.parentNode;
    oParent.removeChild(oBookmark);
}


/* BACKFILLS BOOKMARKS FROM BUFFER */
// calculates empty visible bookmark slots, and backfills from buffer
YAHOO.bm2.bookmarkList.prototype.actionBackfill = function() {
    // get handle of visible bookmarks list
    var aCheckBoxes = this.getCheckBoxes();
    // calculate open spaces in visible list
    var iVisible = (aCheckBoxes.length);
    var iEmptySlots = this.iBookmarkListSize - (iVisible);
    var iTotalBMs = this.oBuffer.getTotalCount();
    var iAvailable = this.oBuffer.countBuffer();
    // if there are less than 20 visible bookmarks
    // and more results are available, go fetch from buffer
    if (iEmptySlots>0 && iAvailable>0) {
        var iNeedToBackfill = (iAvailable < iEmptySlots) ? iAvailable : iEmptySlots;
        // get data from form
        var oNodeData = this.oBuffer.useBufferData(iNeedToBackfill);
        // if results: display, else: go into holding pattern
        if (oNodeData && oNodeData!='fetching') {
            var oNode;
            for (var i=0; i<iNeedToBackfill; i++) {
                // populate node with data
                oNode = this.getNode();
                oNewNode = oNode.populateNode(oNodeData[i]);
                this.insertNode(oNewNode, 'end');
            }
        } else {
            //this.iInt = 0;
        }
    }
}


/* EDIT or ADD AN EXISTING BOOKMARK */
/* ADDS NEW BOOKMARK TO LIST  */
// adds a new bookmark to the list
// psFormData: string of form data we want to save
// piPosition: Index position of where to add (0=start)
YAHOO.bm2.bookmarkList.prototype.actionAddBookmark = function(psFormData, psNewId) {
    if (!psFormData) return;
    // get form data
    var oFormData = this.compileFormData(psFormData);
    // get data from form, and draw node
    var oDataNode = document.getElementById('datanode');
    if (!oDataNode) return;
    // insert new nodes
    var aNewNodes = oDataNode.childNodes;
    for (var i=(aNewNodes.length-1); i>=0; i--) {
        if (aNewNodes[i].tagName=='DIV' || aNewNodes[i].tagName=='INPUT') {
            this.insertNode(aNewNodes[i]);
        }
    }
    // remove "no bookmarks" message and update infoBar
    this.removeNoBookmarks();
    this.updateInfoBar(1);
}
// edit an existing bookmark
YAHOO.bm2.bookmarkList.prototype.actionEditBookmark = function(psFormData, psFormResponse) {
    // bail out if no form data to work with
    if (!psFormData) return;
    // get form data
    var oFormData = this.compileFormData(psFormData);
    // get new node we need
    var oNewNode = document.getElementById('edit'+ oFormData['EDITID']);
    // get nodes we need 
    var aCheckboxes = this.getCheckBoxes();
    var aNodes = [];
    var tmpID;
    for (var i=0; i<aCheckboxes.length; i++) {
        if (aCheckboxes[i].checked) {
            aNodes.push(aCheckboxes[i]);
            break
        }
    }
    if (!aNodes[0]) return;
    var oNodeToChange = document.getElementById(aNodes[0].id.substr(8));
    // make change
    oNodeToChange.innerHTML = oNewNode.innerHTML;
    // remove data node
    var oDataNode = document.getElementById('datanode');
    oDataNode.parentNode.removeChild(oDataNode);
}

YAHOO.bm2.bookmarkList.prototype.actionEditTags = function(psFormData) {
    // bail out if no form data to work with
    if (!psFormData) return;
    // get form data
    var oFormData = this.compileFormData(psFormData);
    // get nodes we need 
    var aCheckboxes = this.getCheckBoxes();
    var aNodes = [];
    var tmpID;
    for (var i=0; i<aCheckboxes.length; i++) {
        if (aCheckboxes[i].checked) {
            tmpID = aCheckboxes[i].id.substr(8);
            aNodes.push(document.getElementById(tmpID));
        }
    }
    // clear & set messages on active nodes
    var aMessages, oMessage, aClr, aParent;
    for (i=0; i<aNodes.length; i++) {
        // remove any previous messages and add new ones
        aMessages = YAHOO.util.Dom.getElementsByClassName('displaymsg', '', aNodes[i]);
        for (ii=0; ii<aMessages.length; ii++)  {
            aMessages[ii].parentNode.removeChild(aMessages[ii]);
        }
        // add new message
        oMessage = document.createElement('div');
        oMessage.className = 'displaymsg';
        oMessage.innerHTML = '<span>' +bm2_translations.messages.MSG_ACTIONMSG_PREFIX +' </span>'+ bm2_translations.messages.MSG_ACTIONMSG_EDITED;
        // insert new message before clear element
        aClr = YAHOO.util.Dom.getElementsByClassName('clr', 'div', aNodes[i]);
        if (aClr[0]) {
            oParent = aClr[0].parentNode;
            oMsg = oParent.insertBefore(oMessage, aClr[0]);
        }
    }
    // edit the tags on display:
    var aTagParent, aTags, sNewLine, aShowTags, aShowTags2;
    var aAddTags = oFormData['TAGS'].split(',');
    var aDelTags = oFormData['RTAGS'].split(',');
    for (i=0; i<aNodes.length; i++) {
        aShowTags = [];
        aShowTags2 = [];
        oTagParent = document.getElementById('bb-tag-'+aNodes[i].id);
        if (oTagParent) {
            aTags = oTagParent.getElementsByTagName('a');
            // loop through tags, make array of tags NOT being deleted/added
            for (ii=0; ii<aTags.length; ii++) {
                isMatch = false;
                for (iii=0; iii<aDelTags.length; iii++) {
                    if (aDelTags[iii]==aTags[ii].innerHTML) {
                        isMatch=true;
                        break;
                    }
                }
                if (!isMatch) {
                    aShowTags.push(aTags[ii].innerHTML);
                }
            }
            // add tags to array that we want to Add
            aShowTags = aShowTags.concat(aAddTags);
            // create new tags strings
            for (ii=0; ii>aShowTags.length; ii++) {
                aShowTags.push('<a href="'+aShowTags[ii]+'">'+aShowTags[ii]+'</a>'); 
            }
            // reprint tags content
            sNewLine = bm2_translations.messages.MSG_NAV_TAGS + ': ' + aShowTags.join(', ');
            oTagParent.innerHTML = sNewLine;
        }
    }
}
// edit existing bookmarks based on MOVE action
YAHOO.bm2.bookmarkList.prototype.actionEditViaMove = function(psFormData) {
    // do something
    return;
}
// takes a string of form data, and returns a JSON object
YAHOO.bm2.bookmarkList.prototype.compileFormData = function(sFormData) {
    // split the data into key/value
    var aFormData = sFormData.split('&');
    var aFormPairs = [];
    var sFormDataString = '{';
    var aTemp = [];
    // go through each pair, and put in temp array
    var aTags = [];
    var aRTags = [];
    for (i=0; i<aFormData.length; i++) {
        var aFormPairs = aFormData[i].split('=');
        if (aFormPairs.length>=2 && aFormPairs[0] && aFormPairs[1]) {
           // if tags, add a counter so these are unique
           if (aFormPairs[0]=='tag%5B%5D') {
               aTags.push(decodeURIComponent(aFormPairs[1]));
           } else if (aFormPairs[0]=='rtag%5B%5D') {
               aRTags.push(decodeURIComponent(aFormPairs[1]));
           } else {
               // add to object
               aTemp.push("'"+aFormPairs[0].toUpperCase()+"':'"+decodeURIComponent(aFormPairs[1])+"'");
           }
        }
    }
    // add tags
    aTemp.push("'TAGS':'"+aTags+"'");
    aTemp.push("'RTAGS':'"+aRTags+"'");
    // evaluate string into object and return
    var oFormData = eval("result={"+aTemp.join(',')+"}");
    return oFormData;
}


/* INTERFACE WITH NODE OBJECT */
// insert a node into the list
// psEnd = (optional) if 'end', insert at end
YAHOO.bm2.bookmarkList.prototype.insertNode = function(poNode, psEnd) {
    // get bookmark list object
    if (!this.oBookmarkArea) {
        this.oBookmarkArea = document.getElementById(this.sBookmarkListId);

    }
    // insert node at the start of the list
    if (!psEnd || psEnd!='end') {
        var oFirstNode = this.oBookmarkArea.firstChild;
        if (oFirstNode) {
            this.oBookmarkArea.insertBefore(poNode, oFirstNode);
        } else {
            this.oBookmarkArea.appendChild(poNode);
        }
    } else {
        this.oBookmarkArea.appendChild(poNode);
    }
}
// populates a node object
YAHOO.bm2.bookmarkList.prototype.getNode = function() {
    if (!this.oBMNode) {
        this.oBMNode = new YAHOO.bm2.bookmarkNode;
    }
    return this.oBMNode;
}


/* UPDATING infobar & No Bookmarks MESSAGE */
YAHOO.bm2.bookmarkList.prototype.removeNoBookmarks = function() {
    var oNoBookmarks = document.getElementById(this.sNoBookmarksId);
    if (oNoBookmarks)
        oNoBookmarks.parentNode.removeChild(oNoBookmarks);
}
YAHOO.bm2.bookmarkList.prototype.updateInfoBar = function(piNumToUpdate) {
    if (piNumToUpdate) {
        // add/subtract from total
        var oInfoTotal = this.getInfoTotalObj();
        if (!oInfoTotal) return;
        var iCurrentTotal = parseInt(this.oInfoTotal.innerHTML);
        if (!isNaN(iCurrentTotal)) {
            var iNewTotal = iCurrentTotal + piNumToUpdate;
            oInfoTotal.innerHTML = iNewTotal;
        }
        // update Last item
        var oInfoEnd = this.getInfoEndObj();
        var iCurrentEnd = parseInt(oInfoEnd.innerHTML);
        if (!isNaN(iCurrentEnd) && iNewTotal && iCurrentEnd>iNewTotal) {
            oInfoEnd.innerHTML = iNewTotal;
        }
        // update Start item (if zero)
        if (iNewTotal===0) {
            var oInfoStart = this.getInfoStartObj();
            oInfoStart.innerHTML = '0';
            oInfoEnd.innerHTML = '0';
        }
    }
}
YAHOO.bm2.bookmarkList.prototype.getInfoTotalObj = function() {
    if (!this.oInfoTotal) this.oInfoTotal = document.getElementById(this.sInfoTotalId);
    return this.oInfoTotal;
}
YAHOO.bm2.bookmarkList.prototype.getInfoEndObj = function() {
    if (!this.oInfoEnd) this.oInfoEnd = document.getElementById(this.sInfoEndId);
    return this.oInfoEnd;
}
YAHOO.bm2.bookmarkList.prototype.getInfoStartObj = function() {
    if (!this.oInfoStart) this.oInfoStart = document.getElementById(this.sInfoStartId);
    return this.oInfoStart;
}/* BOOKMARK NODE MANAGEMENT */
YAHOO.bm2.bookmarkNode = function() {
    this.sNodeId = 'fakenode';
    this.sNewNodeId = 'latestnode';
    this.sSelectNamePrefix = 'IDS[';
    this.sSelectNamePostfix= ']';
    this.sSelectIdPrefix = 'selectBM';
}
// this fetches a clean node for you
YAHOO.bm2.bookmarkNode.prototype.getNewNode = function() {
    var oNode;
    if (!this.oCleanNode) {
        // get empty node
        oNode = document.getElementById(this.sNodeId);
        if (!oNode) return;
        // return node
        oNode.id = this.sNewNodeId;
        this.oCleanNode = oNode;
    } else {
        oNode = this.oCleanNode.cloneNode(true);
    }
    return oNode;
}
// gets references to node elements
YAHOO.bm2.bookmarkNode.prototype.getNodeReferences = function(poNode) {
    var oElements = new Array;
    oElements['prs'] = YAHOO.util.Dom.getElementsByClassName('prs', 'div', poNode)[0];
    oElements['desc'] = YAHOO.util.Dom.getElementsByClassName('desc', 'div', poNode)[0];
    oElements['thumb'] = YAHOO.util.Dom.getElementsByClassName('thumb', 'div', poNode)[0];
    oElements['thumbLink'] = YAHOO.util.Dom.getElementsByClassName('thumblink', 'a', poNode)[0];
    oElements['thumbImg'] = YAHOO.util.Dom.getElementsByClassName('thumbimg', 'img', poNode)[0];
    oElements['url'] = YAHOO.util.Dom.getElementsByClassName('url', 'cite', poNode)[0];
    oElements['title'] = YAHOO.util.Dom.getElementsByClassName('title', 'h4', poNode)[0];
    oElements['titleLink'] = YAHOO.util.Dom.getElementsByClassName('titlelink', 'a', poNode)[0];
    oElements['selectarea'] = YAHOO.util.Dom.getElementsByClassName('selectarea', 'div', poNode)[0];
    oElements['date'] = YAHOO.util.Dom.getElementsByClassName('date', 'strong', poNode)[0];
    oElements['folder'] = YAHOO.util.Dom.getElementsByClassName('folder', 'strong', poNode)[0];
    oElements['tags'] = YAHOO.util.Dom.getElementsByClassName('tags', 'strong', poNode)[0]
    oElements['select'] = YAHOO.util.Dom.getElementsByClassName('chkbx', 'input', poNode)[0];
    oElements['acl'] = YAHOO.util.Dom.getElementsByClassName('acltext', 'em', poNode)[0];
    return oElements;
}
// extract data from node
YAHOO.bm2.bookmarkNode.prototype.extractNodeData = function(poNode) {
    if (!poNode) return;
    // get refs to node
    var oElements = this.getNodeReferences(poNode);
    // extract data
    var oData = {};
    oData.URL = oElements['url'].innerHTML;
    oData.TITLE = oElements['titleLink'].innerHTML;
    oData.DESC = oElements['desc'].innerHTML;
    oData.IMG = oElements['thumbImg'].src;
    oData.ID = poNode.id;
    oData.DATE = oElements['date'].innerHTML;
    return oData;

}
// populates the node with data
// psNodeData is an object containing all the relevent goodness
// psNodeData {DESC, ID, IMG, NUM, TITLE, TRACKURL, URL, ACL}
YAHOO.bm2.bookmarkNode.prototype.populateNode = function(psNodeData) {
    // return if no data
    if (!psNodeData) return;
    // get a new node (cloned)
    var oNode = this.getNewNode();
    oNode.id = psNodeData.ID;
    // get node references
    var oElements = this.getNodeReferences(oNode);
    // populate
    var sURL = (psNodeData.URL.substr(0,7)=='http://' || psNodeData.URL.substr(0,8)=='https://') ? psNodeData.URL : 'http://'+ psNodeData.URL;
    oElements['url'].innerHTML = sURL;
    oElements['title'].innerHTML = '<a href="' +sURL+ '">' + psNodeData.TITLE +'</a>';
    if (psNodeData.IMG)
        oElements['thumb'].innerHTML = '<a href="' +sURL+ '"><img src="'+psNodeData.IMG+'" border="0" class="thumimg"></a>';
    else
        oElements['thumb'].innerHTML = '<a href="' +sURL+ '"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm_nothumbnail.jpg" border="0" class="thumimg"></a>';
    if (psNodeData.DESC)
        oElements['desc'].innerHTML = psNodeData.DESC;
    if (psNodeData.ID) {
        oElements['select'].checked = false;
        oElements['select'].name = this.sSelectNamePrefix + psNodeData.ID + this.sSelectNamePostfix;
        oElements['select'].id = this.sSelectIdPrefix + psNodeData.ID;
    } else {
        oElements['select'].style.display = 'none';
    }
    var sDate = (psNodeData.DATE) ? ' on <strong class="date">'+ psNodeData.DATE +'</strong> ': '';
    //var sDetails = (psNodeData.DETAILS) ? ' - <a href="'+psNodeData.DETAILS+'">Details</a>' : '';
    var sFolder = '';
    var sTags = '';
    oElements['prs'].innerHTML = 'Saved '+ sDate + sFolder + sTags;
    // return
    return oNode;
}
// edit node
YAHOO.bm2.bookmarkNode.prototype.editNode = function(psData, psID) {
    // get references for all node elements
    var oNode = document.getElementById(psID);
    var oElements = this.getNodeReferences(oNode);
    // make changes
    // title
    if (oElements['titleLink'].innerHTML != psData.TITLE) {
        if (psData.TITLE)
             oElements['titleLink'].innerHTML = psData.TITLE;
        else
             oElements['titleLink'].innerHTML = psData.URL;
    }
    // description
    if (oElements['desc'].innerHTML != psData.DESC) {
        if (psData.DESC) 
            oElements['desc'].innerHTML = psData.DESC;
        else
            oElements['desc'].innerHTML = '';
    }
    // acl
    if (psData.USEACL && oElements['acl']) {
        // get text/classname to use
        var sStr, sClassName;
        switch (psData.VISIBLE) {
          case '1': sStr = bm2_translations.messages.MSG_ACL_EVERYONE; sClassName = 'acltext everyone'; break;
          case '2': sStr = bm2_translations.messages.MSG_ACL_CONTACTS; sClassName = 'acltext contacts'; break;
          case '0': default: sStr = bm2_translations.messages.MSG_ACL_PRIVATE; sClassName = 'acltext private'; break;
        }
        // set element
        oElements['acl'].innerHTML = sStr;
        oElements['acl'].className = sClassName;
    }
    // tags
    // TAGS
    if (psData.TAG && oElements['tags']) {
        var aTags = psData.TAG.split(',');
        var sTmp, i;
        for (i=0; i<aTags.length; i++) {
            sTmp = '<a href="/tags/'+ aTags[i] +'">'+ aTags[i] +'</a>';
            aTags[i] = sTmp;
        }
        oElements['tags'].innerHTML = bm2_translations.messages.MSG_NAV_TAGS +': '+ aTags.join(', ');
    }
}
// edit only "folder" information
YAHOO.bm2.bookmarkNode.prototype.editFolder = function(psID, psFID, psFolderName, psYID) {
    // get references for all node elements
    var oNode = document.getElementById(psID);
    var oElements = this.getNodeReferences(oNode);
    // make changes
    if (oElements['folder'] && psFID, psFolderName, psYID) {
        oElements['folder'].innerHTML = 'in <a href="/pages/'+psYID+'?FID='+psFID+'">'+ psFolderName +'</a>';
    }
}
/* INLINEACTIONS */
YAHOO.bm2.inlineActions = function(psActionsId, psActuatorsClassName, psExcludedId, psFID, psPageOffset, psStrings) {
    // return if non-supported browser
    this.bIsValidBrowser = this.checkBrowser();
    // local vars
    this.sInfoBarId = 'selectedinfo';
    this.sInlineActionsId = 'inlineactions';
    this.sActionType = '';
    this.sFormButtonsId = 'actionbttns';
    this.sSaveBttnId = 'savebttn';
    this.sSaveBttnId2 = 'savebttn2';
    this.sCancelBttnId = 'cancelbttn';
    this.sBookmarksId = 'bookmarks';
    this.sBookmarkClassName = 'saveitem';
    this.sFormID = 'actionsform';
    this.oForm = document.getElementById(this.sFormID);
    this.sFormAction = this.oForm.action;
    this.oPageWrapper = document.getElementById('ybmdoc');
    this.sPaginationId = '';
    this.sActionResultsId = 'actionstatus';
    this.oBMNode; // a blank bookmark node
    this.sFormData; // form data, as submitted with ajax
    this.bGotDigDeeper = false;
    this.bForceInfoBarClosed = false; // whether or not infoBar can be open
    this.oSelectBookmarks = false; // js object for select bookmarks code
    // draw menu
    this.sStrings = psStrings;
    this.createMenu();
    // get reference to actuators and add event listeners
    var oActions = document.getElementById(psActionsId);
    this.aActuators = oActions.getElementsByTagName('a');
    for (var i=0; i<this.aActuators.length; i++) {
      if (this.aActuators[i].id != psExcludedId) {
        YAHOO.util.Event.addListener(this.aActuators[i], "click", this.getActionForm, this);
      }
    }
    // get reference to div we want to print to
    this.oWriteElement = document.getElementById('inlineactions');
    // declare some objects we'll use later
    this.bookmarks = new YAHOO.bm2.bookmarkList(psFID, psPageOffset);
}
YAHOO.bm2.inlineActions.prototype.getBookmarks = function() {
  return this.bookmarks;
}
// check browser
YAHOO.bm2.inlineActions.prototype.checkBrowser = function() {
    // check to make sure safari version less than 2.0 (v412)
    // and lower are NOT using inline actions
    var isSafariIndex = navigator.userAgent.indexOf('Safari');
    var isSafari = (isSafariIndex!=-1) ? true : false;
    var iVersion = parseInt((navigator.userAgent.substr(isSafariIndex+7))); 
    // return
    if (isSafari && iVersion<400) return false;
    else return true;
}
// create menu
YAHOO.bm2.inlineActions.prototype.createMenu = function() {
    // make form menu hidden
    var oFormButtons = document.getElementById(this.sFormButtonsId);
    if (this.bIsValidBrowser) {
        oFormButtons.style.display = 'none';
    } else {
        oFormButtons.style.display = 'block';
    }
    // create element
    var oDiv = document.createElement('div');
    oDiv.id = 'actionlinks';
    oDiv.className = 'links';
    //oDiv.innerHTML  += '<a href="*" id="changeview" class="full"><span><b id="changeviewname">'+this.sStrings['viewstyle']+'</b></span></a>';
    if (this.bIsValidBrowser) {
        oDiv.innerHTML  += '<a href="*" class="add"><span><b>'+bm2_translations.messages.MSG_NAV_ADD+'</b></span></a>';
        oDiv.innerHTML  += '<a href="*" class="edit off" id="editact"><span><b>'+bm2_translations.messages.MSG_NAV_EDIT+'</b><em> <b>'+bm2_translations.messages.MSG_NAV_TAGS+'</b></em></span></a>';
        oDiv.innerHTML  += '<a href="*" class="moveto"><span><b>'+bm2_translations.messages.MSG_NAV_MOVE+'</b></span></a>';
        //oDiv.innerHTML  += '<a href="*" class="share"><span><b>'+bm2_translations.messages.MSG_NAV_SHARE+'</b></span></a>';
        oDiv.innerHTML  += '<a href="*" class="delete"><span><b>'+bm2_translations.messages.MSG_NAV_DELETE+'</b></span></a>';
    }
    // append element
    var oParent = document.getElementById('sortcntrl');
    oParent.appendChild(oDiv);
}
// turns off colors on all action buttons
YAHOO.bm2.inlineActions.prototype.turnOffActuators = function() {
    for (var i=0; i<this.aActuators.length; i++) {
        this.aActuators[i].style.backgroundColor = "transparent";
    }
    // turn off options
    if (!this.oViewOptions) {
        this.oViewOptions = document.getElementById('viewoptions');
    }
    if (this.oViewOptions && this.oViewOptions.style.display=="block") {
        this.oViewOptions.style.display = 'none';
    }
}



/* WRITING/CLOSING ACTIONS */
// closes the actions controls
YAHOO.bm2.inlineActions.prototype.close = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking 
    YAHOO.bm2.beacon('action', 'cancel');
    // turn off 'edit tags' js
    if (YAHOO.bm2.oEditTags)
        YAHOO.bm2.oEditTags.purge();
    // reset actuator colors
    obj.turnOffActuators();
    // calculate current obj height & animation speed
    var iCurrHeight = obj.oWriteElement.offsetHeight;
    var iSpeed = iCurrHeight / 500;
    // erase anything inside the inline save area
    obj.oWriteElement.innerHTML = '';
    obj.oWriteElement.style.border = 'none';
    // animate element back to nothing
    var myAnim = new YAHOO.util.Anim(obj.oWriteElement, {height: { to: 0 } }, iSpeed);
    myAnim.animate();
    // reset form
    obj.oForm.action = obj.sFormAction;
    // open up info bar again
    obj.toggleInfoBar(true);
    // open up DigDeeper again
    var oDigDeeper = obj.getDigDeeper();
    if (oDigDeeper && oDigDeeper.style) {
        oDigDeeper.style.display = 'block';
    }
}
YAHOO.bm2.inlineActions.prototype.getDigDeeper = function() {
    if (!this.bGotDigDeeper) {
        this.bGotDigDeeper = true;
        this.oDigDeeper = document.getElementById('digdeeper');
    }
    return this.oDigDeeper;
}
YAHOO.bm2.inlineActions.prototype.reset = function() {
    // reset actuator colors
    this.turnOffActuators();
    // calculate current obj height & animation speed
    var iCurrHeight = this.oWriteElement.offsetHeight;
    var iSpeed = iCurrHeight / 980;
    // erase anything inside the inline save area
    this.oWriteElement.innerHTML = '';
    this.oWriteElement.style.border = 'none';
    // animate element back to nothing
    var myAnim = new YAHOO.util.Anim(this.oWriteElement, {height: { to: 0 } }, iSpeed);
    myAnim.animate();
    // reset form
    this.oForm.action = this.sFormAction;
    // open up info bar again
    this.toggleInfoBar(false);
    // open up DigDeeper again
    var oDigDeeper = this.getDigDeeper();
    if (oDigDeeper && oDigDeeper.style) {
        oDigDeeper.style.display = 'block';
    }
}

// this prints out a loading message
YAHOO.bm2.inlineActions.prototype.loading = function(pbLoad, psActionType) {
    // turn off infobar
    this.toggleInfoBar(false);
    // determine right string to use (loading, or submit-type messages)
    var sStr;
    if (pbLoad) {
        sStr = bm2_translations.messages.MSG_ACTION_LOADING;
    } else {
        switch (psActionType) {
          case 'delete': sStr = bm2_translations.messages.MSG_ACTION_DELETING; break;
          case 'moveto': sStr = bm2_translations.messages.MSG_ACTION_MOVING; break;
          case 'share': sStr = bm2_translations.messages.MSG_ACTION_SENDING; break;
          default: sStr = bm2_translations.messages.MSG_ACTION_SAVING; break;
        }
    }
    // print out message
    this.write('<div class="message loading"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2//bm2_indicator_arrow.gif" height="16" width="16" alt="" class="indicator">'+ sStr +'</div>', pbLoad, 'loading');
}
// this prints out content, without animation
YAHOO.bm2.inlineActions.prototype.quickWrite = function(pString) {
    // check for content
    if (!pString) return;
    // remove DigDeeper if there
    var oDigDeeper = this.getDigDeeper();
    if (oDigDeeper && oDigDeeper.style) {
        oDigDeeper.style.display = 'none';
    }
    // print
    this.oWriteElement.innerHTML = pString;
    this.oWriteElement.style.height = 'auto';
}
// this prints out content, with animation
YAHOO.bm2.inlineActions.prototype.write = function(pString, psIsLoading, psType) {
    // check for content
    if (!pString) return;
    // remove DigDeeper if there
    var oDigDeeper = this.getDigDeeper();
    if (oDigDeeper && oDigDeeper.style) {
        oDigDeeper.style.display = 'none';
    }
    // get current height, and set module to that height
    var iCurrHeight = this.oWriteElement.offsetHeight;
    // place content
    var oInnerCntnt = document.createElement('div');
    oInnerCntnt.id = 'innerContent';
    oInnerCntnt.style.visibility = 'hidden';
    oInnerCntnt.innerHTML = this.stripJS(pString);
    // save off old element height
    var iCurrHeight = this.oWriteElement.offsetHeight;
    this.oWriteElement.style.height = iCurrHeight;
    this.oWriteElement.innerHTML = '';
    this.oWriteElement.style.borderBottom = "1px solid #ccc";
    this.oWriteElement.appendChild(oInnerCntnt);
    // check for close button
    this.addCloseButton();
    // calculate inner height 
    var iNewHeight = 0;
    // do JS
    if (psType=='actionSuccess')  {
        this.manualJS();
    }
    // get new size of module
    iNewHeight = this.getHeight(oInnerCntnt) + 10;
    // animate module, (only if big difference in height)
    var iHeightDifference = iNewHeight - iCurrHeight;
    var isLoadingFromBig = (psIsLoading && iNewHeight< iCurrHeight);
    if ((iHeightDifference > 10 || iHeightDifference < -10) && !isLoadingFromBig) {
        var iSpeed = iNewHeight / 500;
        var myAnim = new YAHOO.util.Anim(this.oWriteElement, {height: { from: iCurrHeight, to: iNewHeight } }, iSpeed);
        myAnim.onComplete.subscribe(this.doneAnimation);
        myAnim.animate();
        return iNewHeight;
    }
}
YAHOO.bm2.inlineActions.prototype.addCloseButton = function() {
    var oClose = document.getElementById('closemod');
    if (oClose) {
        var aLinks = oClose.getElementsByTagName('a');
        if (aLinks && aLinks[0]) {
            YAHOO.util.Event.addListener(aLinks[0], "click", this.close, this);
        }
    }
}
YAHOO.bm2.inlineActions.prototype.stripJS = function(pString) {
    var aTemp = pString.split('<script');
    return aTemp[0];
}
// when animation is done, make content visible
YAHOO.bm2.inlineActions.prototype.doneAnimation = function() {
   // make visible
   var oInnerCntnt = document.getElementById('innerContent');
   if (oInnerCntnt) {
       oInnerCntnt.style.visibility = 'visible';
       oInnerCntnt.style.height = 'auto';
   }
}
// calculates height of content module, before it's displayed
YAHOO.bm2.inlineActions.prototype.getHeight = function(poOriginal) {
    var sOldPosition, iHeight;
    // new method
    if (poOriginal) {
        // remember old style.position
        sOldPosition = poOriginal.style.position;
        poOriginal.style.visibility = 'hidden';
        poOriginal.style.position = 'absolute';
        // get height
        iHeight = poOriginal.offsetHeight;
        // revert everything
        poOriginal.style.position = sOldPosition;
        poOriginal.style.visibility = 'visible';
        return iHeight;
    } else { 
        return 0;
    }

    // clone node
    var oClone =  poOriginal.cloneNode(true);
    oClone.id = "cloneid";
    oClone.style.display = "block";
    oClone.style.height = "auto";
    oClone.style.position = "absolute";
    oClone.style.zIndex = 1000;
    //oClone.style.visibility = "hidden"
    oClone.style.top = 0
    oClone.style.left = -2000 +'px';
    oClone.style.left = '0px';
    // append and calculate
    this.oPageWrapper.appendChild(oClone);
    iHeight = oClone.offsetHeight;
    oClone.parentNode.removeChild(oClone);
    // return
    return iHeight;
}




/* HANDLING one/many EDIT OPTIONS */
// checks to see if multiple edit buttons have been pressed
// 0, 1 check = 'edit' | 2+ checked = 'edit all'
YAHOO.bm2.inlineActions.prototype.checkEditActuator = function(piActiveCheckboxes) {
    // change actuator
    if (!this.oEditAct) {
        this.oEditAct = document.getElementById('editact');
    }
    if (this.oEditAct) {
        if (piActiveCheckboxes>=2) this.oEditAct.className='edit on';
        else this.oEditAct.className='edit off';
    }
    // check if the "edit" dialogue is actually open
    var oOneEdit = document.getElementById('editbookmark');
    var oMultiEdit = document.getElementById('editmultiple'); 
    // switch mode
    if ((this.oEditAct.className=='edit off' && oMultiEdit) || (this.oEditAct.className=='edit on' && oOneEdit)) {
        var oActuator = document.getElementById('editact');
        if (oActuator)  {
            this.displayActionForm(oActuator.className, oActuator);
        }
    }
}

YAHOO.bm2.inlineActions.prototype.getConnection = function() {
    if (!this.oConnect) {
        this.oConnect = YAHOO.util.Connect;
        this.oConnection = false;
    } else {
        if (YAHOO.util.Connect.isCallInProgress(this.oConnection)) {
            YAHOO.util.Connect.abort(this.oConnection);
        };
    };
    return this.oConnect;
}




/* GET ACTION FORMS */
YAHOO.bm2.inlineActions.prototype.getActionForm = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;

    // fake stuff for testing
//    obj.bookmarks.actionRemoveBookmarks();
//    obj.bookmarks.actionBackfill();
//    return;

    // set action
    obj.sActionType = this.className;
    // display form
    obj.displayActionForm(obj.sActionType, this);
}
YAHOO.bm2.inlineActions.prototype.displayActionForm = function(sActionType, poThis) {
    this.sActionType = sActionType;
    // cancel out bg color of other items
    this.turnOffActuators();
    // make call
    var sURL = '/admin/ShowAddBM';
    var sSLK;
    switch (sActionType) {
        case 'add':      sURL = '/admin/ShowAddBM'; sSLK = 'addbkmk'; break;
        case 'edit':     sURL = '/admin/ShowEditBM'; sSLK = 'editbkmk'; break;
        case 'edit on':  sURL = '/admin/ShowEditBM'; sSLK = 'editbkmk'; break;
        case 'edit off': sURL = '/admin/ShowEditBM'; sSLK = 'editbkmk'; break;
        case 'moveto':   sURL = '/admin/ShowMoveToBM'; sSLK = 'movebkmk'; break;
        case 'share':    sURL = '/admin/showsharebm'; sSLK = 'sendbkmk'; break;
        case 'delete':   sURL = '/admin/DeleteBMConfirm'; sSLK = 'delbkmk'; break;
    }
    // make beacon call
    var sSEC = 'actionbar';
    YAHOO.bm2.beacon(sSEC, sSLK);
    // assign callback functions
    var callback = {
        success: this.getActionSuccess,
        failure: this.getActionFail,
        argument: [this]
    }
    // print out loading notice and color background
    this.loading(true, sActionType);
    poThis.style.backgroundColor = "#F8F3D6";
    poThis.blur();
    document.cursor = 'waiting';
    // make the connection, add custom header for Symfony support
    var oConnect = this.getConnection();
    if (oConnect) {
        oConnect.setForm(this.sFormID);
        oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
        this.oConnection = oConnect.asyncRequest('POST', sURL, callback, null);
    }
}
YAHOO.bm2.inlineActions.prototype.getActionFail = function(o) {
    // reset cursor
    document.cursor = 'default';
    // construct error
    var obj = o.argument[0];
    sError =  '<div class="actioncntrl"><div class="hd"><h3 id="pagetitle">Add a Bookmark</h3></div><div class="bd">';
    sError += '<p class="error">'+bm2_translations.messages.MSG_ERROR+'</p>';
    sError += '</div></div>';
    // print out
    var obj = o.argument[0];
    obj.write(sError, false, 'actionFail');
}
YAHOO.bm2.inlineActions.prototype.getActionSuccess = function(o) {
    document.cursor = 'default';
    // get args
    var obj = o.argument[0];
    // update infobar
    obj.toggleInfoBar(false);
    // print out success
    obj.write(o.responseText, false, 'actionSuccess');
    // change form to submit to right location
    var sNewAction = '';
    switch (obj.sActionType) {
        case 'add': sNewAction      = '/admin/SaveBM'; break;
        case 'edit': sNewAction     = '/admin/SaveEditedBM'; break;
        case 'edit on': sNewAction  = '/admin/SaveEditedBMMultiple'; break;
        case 'edit off': sNewAction = '/admin/SaveEditedBM'; break;
        case 'moveto': sNewAction   = '/admin/MoveToBM'; break;
//        case 'share': sNewAction    = '/admin/sendemail'; break;
        case 'delete': sNewAction   = '/admin/DeleteBM'; break;
    }
    obj.oForm.action = sNewAction;
    // add event listener to wait for 'enter key' 
    obj.captureEnterKey();
}
YAHOO.bm2.inlineActions.prototype.captureEnterKey = function() {
    var aInputFields = this.oWriteElement.getElementsByTagName('input');
    // add listeners to open items
    for (var i in aInputFields) {
        if (aInputFields[i].className!='suggestedtag') 
            YAHOO.util.Event.addListener(aInputFields[i], "keypress", this.cancelEnterKey, this);
    }
}
YAHOO.bm2.inlineActions.prototype.cancelEnterKey = function(e, obj) {
    // only do this to enter key
    if (e.keyCode==13) {
        // cancel out enter
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false; 
        // force submit of form
        if (obj.sActionType=='add' || obj.sActionType=='edit off') {
            obj.submitForm(e, obj);
        }
    }
}
YAHOO.bm2.inlineActions.prototype.manualJS = function() {
    // remove info bar and update span info bar
    if (this.oSelectBookmarks) {
        this.oSelectBookmarks.clearInfoBars();
        this.oSelectBookmarks.updateInfoBar();
    }
    // add event handler to cancel button
    var oCancel = document.getElementById(this.sCancelBttnId);
    YAHOO.util.Event.addListener(oCancel, "click", this.close, this);
    // add event listener to submit button
    var oSaveBttn = document.getElementById(this.sSaveBttnId);
    YAHOO.util.Event.addListener(oSaveBttn, "click", this.submitForm, this);
    var oSaveBttn2 = document.getElementById(this.sSaveBttnId2);
    YAHOO.util.Event.addListener(oSaveBttn2, "click", this.submitForm, this);
    // turn off any JS we don't need from the last inline action
    if (YAHOO.bm2.oEditTags)
        YAHOO.bm2.oEditTags.purge();
    // manual fire JS
    switch (this.sActionType) {
        case 'add':
            YAHOO.bm2.oLoadSave = new YAHOO.bm2.saveBM(['addURL','addTitle','addNotes','addTags'], '#333', '#aaa');
            if (YAHOO.bm2.myTags) {
                YAHOO.bm2.suggestedTags.init('addTags','tagfields','#333','inline', YAHOO.bm2.myTags.results);
            } else {
                YAHOO.bm2.suggestedTags.init('addTags','tagfields','#333','inline');
            }
            YAHOO.bm2.suggestedTags.useTagsOnLoad();
            YAHOO.bm2.thisRecs = new YAHOO.bm2.recommendations('contacts');
            break;
        case 'edit': case 'edit off':
            if (YAHOO.bm2.myTags) {
                YAHOO.bm2.suggestedTags.init('addTags','tagfields','#333','inline', YAHOO.bm2.myTags.results);
            } else {
                YAHOO.bm2.suggestedTags.init('addTags','tagfields','#333','inline');
            }
            YAHOO.bm2.suggestedTags.useTagsOnLoad();
            YAHOO.bm2.thisRecs = new YAHOO.bm2.recommendations('contacts');
            break;
        case 'edit on':
            YAHOO.bm2.oLoadSave = new YAHOO.bm2.saveBM(['tagadd'], '#333', '#aaa');
            YAHOO.bm2.oEditTags = new YAHOO.bm2.editTags(this); 
            break;
//        case 'share': 
//            YAHOO.bm2.oLoadSave = new YAHOO.bm2.saveBM(['remail','addIM'], '#333', '#aaa');
//            YAHOO.bm2.oSend = new YAHOO.bm2.send(this);
            // add js
//            YAHOO.bm2.oEmail = new YAHOO.bm2.email(this);
//            break;
        case 'moveto':
            this.initMoveDHTML();
            break;
    }
}

/* SUBMIT FORM -- this handles submission through AJAX */
YAHOO.bm2.inlineActions.prototype.submitForm = function(e, obj) {
    // cancel out default submit
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    var sSLK;
    switch (obj.sActionType) {
        case 'add':      sSLK = 'save'; break;
        case 'edit':     sSLK = 'edit'; break;
        case 'edit on':  sSLK = 'fin'; break;
        case 'edit off': sSLK = 'edit'; break;
        case 'moveto':   sSLK = 'move'; break;
//        case 'share':    sSLK = 'email'; break;
        case 'delete':   sSLK = 'del'; break;
    }
    // make beacon call
    var sSEC = 'action';
    YAHOO.bm2.beacon(sSEC, sSLK);
    // create callback
    var callback = {
        success: obj.getSubmitSuccess,
        failure: obj.getActionFail,
        argument: [obj]
    }
    // make the connection, add custom header for Symfony support
    var oConnect = obj.getConnection();
    if (oConnect) {
        oConnect.setForm(obj.oForm);
        obj.sFormData = oConnect._sFormData;
        oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
        obj.oConnection = oConnect.asyncRequest('POST', obj.oForm.action, callback, null);
        // print out loading notice 
        obj.loading(false, obj.sActionType);
        // use waiting icon
        document.cursor = 'waiting';
    }
}
YAHOO.bm2.inlineActions.prototype.getSubmitSuccess = function(o, obj) {
    // write out success
    var obj = o.argument[0];
    obj.write(o.responseText, false, 'submitSuccess');
    // reset icon
    document.cursor = 'default';
    // make sure this really WAS a success
    // (error page being returned will return as success, so we want to compare
    //  with a hidden ID on the page
    var oSuccessValue = document.getElementById(obj.sActionResultsId);
    if (oSuccessValue && oSuccessValue.innerHTML=='error') return;
    // if success, handle removing items
    switch (obj.sActionType) {
        case 'moveto':
            // move and backfill from buffer
        	YAHOO.bm2.BookmarksManager.removeBookmarkFromList(true); 
        	obj.bookmarks.actionMoveBookmarks(obj.sFormData); 
        	obj.bookmarks.actionBackfill(); 
            // remove select all, and make sure all checkboxes are coloured correctly
            obj.oSelectBookmarks.turnOffSelectAll(); 
            obj.oSelectBookmarks.clearColours();
        	break;
        case 'delete':   obj.bookmarks.actionRemoveBookmarks(); obj.bookmarks.actionBackfill(); obj.oSelectBookmarks.turnOffSelectAll(); break;
        case 'edit on':  obj.bookmarks.actionEditTags(obj.sFormData); break;
        case 'edit off': obj.bookmarks.actionEditBookmark(obj.sFormData, o.responseText); obj.bookmarks.actionBackfill(); break;
        case 'add': 
            var oNewId = document.getElementById('newbmid');
            var sNewId = (oNewId && oNewId.innerHTML!='') ? oNewId.innerHTML : '';
            //obj.bookmarks.actionRemoveLastBookmark(); 
            obj.bookmarks.actionAddBookmark(obj.sFormData, sNewId); break;
    }
    // reset checkboxes in selectBookmarks object
    // we do this because if we add/remove bookmarks, we need to also
    // update the array of bookmarks in selectBookmarks so we don't have to 
    // perform expensive lookup operations each time we want an list of checkboxes
    if (obj.oSelectBookmarks) { // set externally
        obj.oSelectBookmarks.getCheckboxes(true);
    }
    // update toolbar
    YAHOO.bm2.updateToolbar();
}


// this toggles the info bar on/off because we don't need this while
// inline actions are open (duplicate info)
YAHOO.bm2.inlineActions.prototype.toggleInfoBar = function(pbOnOff) {
    var oInfoBar, oParent, oInlineActions;
    oInfoBar = document.getElementById(this.sInfoBarId);
    if (!oInfoBar) return;
    // toggle
    if (pbOnOff) {
        this.bForceInfoBarClosed = false;
        // turn on (make 'block' first to reduce 
        // weird animation 'chopiness')
        oInfoBar.style.display = 'block';
        if (this.oSelectBookmarks) {
            this.oSelectBookmarks.updateInfoBar();
        }
    } else {
        this.bForceInfoBarClosed = true;
        // remove
        oInfoBar.style.display = 'none';
    }
}

/* MOVE DHTML */
YAHOO.bm2.inlineActions.prototype.initMoveDHTML = function() {
    var oMoveSelect = document.getElementById('mergeSelect');
    YAHOO.util.Event.addListener(oMoveSelect, 'change', this.handleMoveDHTML, this);
}
YAHOO.bm2.inlineActions.prototype.handleMoveDHTML = function(e, obj) {
    // find out which element has been selected
    var oTarget = Evt.getTarget(e);
    var aOptions = oTarget.getElementsByTagName('option');
    for (var i=0; i<aOptions.length; i++) {
        if (aOptions[i].selected) {
            var oSelected = aOptions[i];
            break;
        }
    }
    // move folder name into a hidden form field
    var oNewFolderField = document.getElementById('newfoldername');
    var sValue = oSelected.innerHTML.replace(/&nbsp;/g, "");
    sValue = sValue.replace("'", "\\'");
    if (oNewFolderField && sValue) {
       oNewFolderField.value = sValue;
    }
}/* Interesting today Inline Actions */
YAHOO.bm2.itInline = function() {
    // ids & classNames
    this.sBookmarkListId = 'bookmarks';
    this.sSaveClassName = 'save';
    this.sListItemClassName = 'saveitem';
    this.sCancelBttnId = 'cancelbttn';
    this.sSaveBttnId = 'savebttn';
    this.oBookmark = false;
    this.sFormId = 'interestingform';
    this.sActionResultsId = 'actionstatus';
    // array to hold original content
    this.sOrigContent;
    // add event listeners
    this.aSaveBttns = YAHOO.util.Dom.getElementsByClassName(this.sSaveClassName, 'a', this.sBookmarkListId);
    YAHOO.util.Event.addListener(this.aSaveBttns, "click", this.getSaveForm, this);
}
// save form methods
YAHOO.bm2.itInline.prototype.getSaveForm = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // print out loading notice and color background
    if (obj.oBookmark) obj.close(e, obj);
    obj.oBookmark = obj.getBookmark(this);
    obj.sOrigContent = obj.oBookmark.innerHTML;
    obj.loading(true);
    document.cursor = 'waiting';
    // assign callback functions
    var callback = {
        success: obj.getFormSuccess,
        failure: obj.getFormFail,
        argument: [obj]
    }
    // make the connection, add custom header for Symfony support
    var sURL = this.href + '&type=interestingtoday';
    var oConnect = YAHOO.util.Connect;
    oConnect.setForm(obj.sFormID);
    oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
    oConnect.asyncRequest('GET', sURL, callback, null);
}
YAHOO.bm2.itInline.prototype.getFormSuccess = function(o) {
    // get 'this' obj
    var obj = o.argument[0];
    // print out
    obj.write(o.responseText);
    // add event handler to cancel button
    var oCancel = document.getElementById(obj.sCancelBttnId);
    YAHOO.util.Event.addListener(oCancel, "click", obj.close, obj);
    // add event listener to submit button
    var oSaveBttn = document.getElementById(obj.sSaveBttnId);
    YAHOO.util.Event.addListener(oSaveBttn, "click", obj.submitForm, obj);
    // force fire JS
    YAHOO.bm2.oLoadSave = new YAHOO.bm2.saveBM(['addNotes'], '#333', '#aaa');
    YAHOO.bm2.suggestedTags.init('addTags','tagfields','#333','inline');
    YAHOO.bm2.suggestedTags.useTagsOnLoad();
    YAHOO.bm2.thisRecs = new YAHOO.bm2.recommendations('contacts');
}
YAHOO.bm2.itInline.prototype.getFormFail = function(o) {
    // reset cursor
    document.cursor = 'default';
    // get 'this' obj
    var obj = o.argument[0];
    // construct error
    var sError = '<p class="loading error">'+ bm2_translations.messages.MSG_ERROR +'</p>';
    // print out
    obj.write(sError);
}



/* submit form */
YAHOO.bm2.itInline.prototype.submitForm = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // create callback
    var callback = {
        success: obj.getSubmitSuccess,
        failure: obj.getFormFail,
        argument: [obj]
    }
    // make the connection, add custom header for Symfony support
    var oConnect = YAHOO.util.Connect;
    // set form
    obj.oForm = document.getElementById(obj.sFormId);
    oConnect.setForm(obj.oForm);
    obj.sFormData = oConnect._sFormData;
    // set headers
    oConnect.initHeader('X-Requested-With', 'XMLHttpRequest');
    oConnect.asyncRequest('POST', '/admin/SaveBM', callback, null);
    // write out loading notice
    obj.loading(false);
    // use waiting icon
    document.cursor = 'waiting';
}
YAHOO.bm2.itInline.prototype.getSubmitSuccess = function(o) {
    // get obj
    var obj = o.argument[0];
    // print out success
    obj.write(obj.sOrigContent + o.responseText);
    // remove save notice
    var aSaveAct = YAHOO.util.Dom.getElementsByClassName(obj.sSaveClassName, 'a', obj.oBookmark);
    for (i in aSaveAct) {
        aSaveAct[i].style.display = 'none';
    }
}

/* helpers */
YAHOO.bm2.itInline.prototype.close = function(e, obj) {
    if (obj.oBookmark && obj.sOrigContent) {
        obj.oBookmark.innerHTML = obj.sOrigContent;
        // add event listener
        var aSaveBttn = YAHOO.util.Dom.getElementsByClassName(obj.sSaveClassName, 'a', obj.oBookmark);
        YAHOO.util.Event.addListener(aSaveBttn, "click", obj.getSaveForm, obj);
        // clear objects
        obj.sOrigContent = '';
        obj.oBookmark = false;
    }
}
YAHOO.bm2.itInline.prototype.getBookmark = function(poSaveAct) {
    var oBookmark = YAHOO.bm2.getAncestorByClassName(this.sListItemClassName, poSaveAct);
    return oBookmark;
}
YAHOO.bm2.itInline.prototype.write = function(psMessage) {
    this.oBookmark.innerHTML = '';
    this.oBookmark.innerHTML = '<div id="saveaction">'+psMessage +'</div>';
}
YAHOO.bm2.itInline.prototype.loading = function (pbLoad) {
    var sStr = (!pbLoad) ? bm2_translations.messages.MSG_ACTION_SAVING : bm2_translations.messages.MSG_ACTION_LOADING;
    var sMsg = '<div id="saveaction"><div class="loading"><img src="http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_indicator_arrow.gif" height="16" width="16" alt="" class="indicator">'+sStr+'</div>';
    this.write(sMsg);
}
/* ACTION CHECKBOXES */
// psListId = ID of entire list (ul or ol)
// psListItemClassName = className of each list item
// psListItemContentClass = className of the content of each item
YAHOO.bm2.selectBookmarks = function (psListId, psListItemClassName, psListItemContentClass) {
    if (!document.getElementById) return;
    // local vars
    this.bAlreadyUsedInfoBar = false;
    this.sInfoBarId = 'selectedinfo';
    this.sInfoBarTextId = 'selectedinfotext';
    this.sInlineInfoBarId = 'infospan';
    this.sSelectAreaClassName = 'selectarea';
    this.onColor = "#F3F4F6";
    this.onBorderColor = "#DADBDF";
    this.offColor = "#FFF";
    this.offBorderColor = "#F5F5F5";
    this.sListItemClassName = psListItemClassName;
    this.sListItemContentClass = psListItemContentClass;
    this.sSelectAllId = 'selectallinput';
    this.oSelectAll = false;
    // interaction with inline actions for 'edit' && 'edit tags'
    this.bUseInlineActions = false;
    this.oInlineActions = false;
    // viewstyle
    this.sViewStyle = "large";             // default view style
    this.sViewStyleId = 'viewstyle';       // module ID we can grab viewstyle from (from className)
    // get reference to bookmark list
    this.oList = document.getElementById(psListId);
}

/* SELECT ALL BUTTON */
// init select all button
YAHOO.bm2.selectBookmarks.prototype.initializeSelectAll = function () {
    this.oSelectAll = this.getSelectAll();
    if (this.oSelectAll) {
        YAHOO.util.Event.addListener(this.oSelectAll, "click", this.handleSelectAll, this);
    }
}
YAHOO.bm2.selectBookmarks.prototype.getSelectAll = function () {
    if (this.oSelectAll) return this.oSelectAll;
    else { this.oSelectAll = document.getElementById(this.sSelectAllId); }
    return this.oSelectAll;
}
YAHOO.bm2.selectBookmarks.prototype.handleSelectAll = function(e, obj) {
    // tracking
    YAHOO.bm2.beacon('actionbar', 'selectall');
    // determine new state
    var bNewState = obj.oSelectAll.checked;
    // loop through all checkboxes and turn on/off
    var aCheckBoxes = obj.getCheckboxes(true);
    var iMaxLength = (aCheckBoxes.length>20) ? 20 : aCheckBoxes.length;
    for (var i=0; i<iMaxLength; i++) {
        if (aCheckBoxes[i].checked!=bNewState) {
            if (aCheckBoxes[i].checked != bNewState) {
                obj.toggleCheckbox(aCheckBoxes[i], true, true);
            }
        }
    }
    // update infobar
    var iActiveCount = (bNewState) ? iMaxLength : 0;
    obj.updateInfoBar(iActiveCount);
    // update actions nav
    obj.updateActionsNav(iActiveCount);
}
YAHOO.bm2.selectBookmarks.prototype.turnOffSelectAll = function() {
    var oSelectAll = this.getSelectAll();
    oSelectAll.checked = false;
}

/* CHECKBOXES */
// init checkboxes
YAHOO.bm2.selectBookmarks.prototype.initializeCheckboxes = function() {
    // get each bookmark checkbox
    this.aCheckBoxes = this.getCheckboxes(true);
    this.aMeta = new Array;
    // loop through each checkbox to:
    // reset checkboxes, and add background to selectarea
    var iActiveCount = 0;
    for (var i=0; i<this.aCheckBoxes.length; i++) {
        // reset checkboxes on page refresh
        if (this.aCheckBoxes[i].checked) {
            this.toggleColours(false, this.aCheckBoxes[i]);
            iActiveCount++;
        }
        // add background to selectarea 
        this.aMeta[i] = this.aCheckBoxes[i].parentNode.parentNode;
    }
    // reset 'select all' if we have to
    var oSelectAll = this.getSelectAll();
    if (iActiveCount==this.aCheckBoxes.length) {
        oSelectAll.checked = true;
    } else {
        oSelectAll.checked = false;
    }
    // add event listeners
    YAHOO.util.Event.purgeElement(this.oList);
    YAHOO.util.Event.addListener(this.oList, "click", this.handleSingleClick, this);
    YAHOO.util.Event.purgeElement(this.aMeta);
    YAHOO.util.Event.addListener(this.aMeta, "mouseover", this.useCursor, this);
    // resize the 'select' area
    this.resizeArea();
    // update infobar
    this.updateInfoBar(iActiveCount);
    // update the action bar 'edit' vs. 'edit tags' 
    this.updateActionsNav(iActiveCount);
}
// pbRefresh = true (get fresh list) | false (use existing list to aid performance)
YAHOO.bm2.selectBookmarks.prototype.getCheckboxes = function(pbGetFresh) {
    if (!pbGetFresh && this.aCheckBoxes) {
        return this.aCheckBoxes;
    }
    this.aCheckBoxes = YAHOO.util.Dom.getElementsByClassName('chkbx', 'input', 'visiblebms');
    return this.aCheckBoxes;
}
// 
YAHOO.bm2.selectBookmarks.prototype.clearColours = function() {
    // get checkboxes
    var oCheckBoxes = this.getCheckboxes(true);
    // toggle colours of on ones and off ones
    var bOnOff;
    for (var i=0; i<oCheckBoxes.length;  i++) {
        bOnOff = (oCheckBoxes[i].checked) ? false : true;
        this.toggleColours(bOnOff, oCheckBoxes[i]);
    }
}
// handle click on the entire list of bookmarks, we'll figure
// out which one was clicked here using 'event delegation'
YAHOO.bm2.selectBookmarks.prototype.handleSingleClick = function(e, obj) {
    // click checkbox and colour area
    var oTarget = YAHOO.util.Event.getTarget(e);
    // turn on checkbox 
    if (oTarget.className == 'selectarea' || oTarget.className == 'select') {
        // get checkbox node
        var aCheckboxes = oTarget.getElementsByTagName('input');
        if (aCheckboxes && aCheckboxes[0]) {
            obj.toggleCheckbox(aCheckboxes[0], true, false);
        }
    } else if (oTarget.className == 'chkbx') {
        obj.toggleCheckbox(oTarget, false, false);
    }
}
// this turns checkboxes on and off based on user-click
// poCheckbox = the checkbox we want to toggle
// pbDoClick = true (click) , false (don't click, it's handled elsewhere)
// pbFromSelectAll = if from select all, don't bother handling select all stuff
YAHOO.bm2.selectBookmarks.prototype.toggleCheckbox = function(poCheckbox, pbDoClick, pbFromSelectAll) {
    // check or uncheck box
    if (pbDoClick) {
        poCheckbox.checked = (poCheckbox.checked) ? false: true;
    }
    var bCurrentStatus = poCheckbox.checked;
    var bChangeStatusTo = (bCurrentStatus) ? false : true;
    // toggle colours on/off
    this.toggleColours(bChangeStatusTo, poCheckbox);
    // only do this stuff on an individual item-click
    if (!pbFromSelectAll) {
        // tracking
        var sSLK = (bCurrentStatus) ? 'select' : 'deselect';
        YAHOO.bm2.beacon('bkvw', sSLK);
        // update 'select all' box if we're unchecking items
        var iCheckboxesCount = this.getCheckboxes().length;
        var iActiveCount = this.countActiveCheckboxes();
        var oSelectAll = this.getSelectAll();
        if (iActiveCount == iCheckboxesCount)
            oSelectAll.checked = true;
        else 
            oSelectAll.checked = false;
        // toggle infobar
        this.updateInfoBar(iActiveCount);
        // toggle inline actions ('edit' and 'edit tags')
        this.updateActionsNav(iActiveCount);
    }
}
YAHOO.bm2.selectBookmarks.prototype.countActiveCheckboxes = function() {
    var aCheckboxes = this.getCheckboxes(false);
    var iActiveCount = 0;
    for (var i=0; i< aCheckboxes.length; i++) {
        if (aCheckboxes[i].checked)
            iActiveCount++;
    }
    return iActiveCount;
}
YAHOO.bm2.selectBookmarks.prototype.toggleColours = function (pbOnOff, pThis) {
    // change background colors on items
    var oBookmark = YAHOO.bm2.getAncestorByClassName(this.sListItemClassName, pThis);
    var aContent = YAHOO.util.Dom.getElementsByClassName(this.sListItemContentClass, 'div', oBookmark);
    if (aContent.length>0 && aContent[0]) {
      aContent[0].style.backgroundColor = (pbOnOff) ? this.offColor : this.onColor;
      aContent[0].style.borderColor = (pbOnOff) ? this.offBorderColor : this.onBorderColor;
    }
    // change background of selectarea
    var oMeta = (pThis.className=="selectarea") ? pThis : YAHOO.bm2.getAncestorByClassName('selectarea', pThis);
    if (oMeta) {
        oMeta.style.backgroundColor = (pbOnOff) ? this.offBorderColor : this.onBorderColor;
    }
}

/* RESIZE AND CURSOR MOUSEOVERS */
YAHOO.bm2.selectBookmarks.prototype.resizeArea = function() {
    var iTotalHeight=0, oParentNode;
    // get items
    this.aList = YAHOO.util.Dom.getElementsByClassName(this.sSelectAreaClassName, 'div', this.oList);
    // add onclick to each background
    var iTotalHeight = 0;
    for (var i=0; this.aList.length; i++) {
        iTotalHeight = 0;
        try {
            oParentNode = this.aList[i].parentNode;
            if (oParentNode.id!='fakenode') {
                iTotalHeight = oParentNode.offsetHeight-1;
                this.aList[i].style.height = (iTotalHeight) + 'px';
            }
        } catch (e) {
            return;
        }
    }
}
YAHOO.bm2.selectBookmarks.prototype.useCursor = function(e, obj) {
    e.cancelBubble = true;
    if (this && this.style) {
        this.style.cursor = 'default';
    }
}


/* INFO BAR */
YAHOO.bm2.selectBookmarks.prototype.updateInfoBar = function(piActiveCount) {
    // count how many are on/off
    if (!piActiveCount)
        piActiveCount = this.countActiveCheckboxes();
    // change inline infobar
    this.makeInlineInfoBarChange(piActiveCount);
    // change module infobar
    this.makeInfoBarChange(piActiveCount);
}
// this updates the InfoBar text in the header of an Actions Nav module
YAHOO.bm2.selectBookmarks.prototype.makeInlineInfoBarChange = function(piActiveCount) {
    // get object we want to print to
    var oElement = this.getInlineInfoBar();
    if (!oElement) return;
    // decide whether to show or hide element
    if (piActiveCount && piActiveCount>0) {   // show element 
        // build text to use
        var sText = (piActiveCount==1) ? bm2_translations.messages.MSG_ITEMS_SINGULAR : bm2_translations.messages.MSG_ITEMS_PLURAL;
        var sString =  piActiveCount +' '+ sText;
        // update text
        if (oElement.style.display)
            oElement.style.display = 'span';
        oElement.innerHTML = sString;
    } else {
        // hide element
        oElement.innerHTML = '0 '+  bm2_translations.messages.MSG_ITEMS_PLURAL;
    }
}
// this updates the InfoBar
YAHOO.bm2.selectBookmarks.prototype.makeInfoBarChange = function(piActiveCount) {
    // if no object, don't do anything
    var oElement = this.getInfoBar();
    if (!oElement) return;
    // don't do anything if 'inline actions' is open and has taken control over infobar
    if (this.oInlineActions && this.oInlineActions.bForceInfoBarClosed==true) 
        return;
    // decide whether to show or hide element
    var oParent = oElement.parentNode;
    if (piActiveCount && piActiveCount>0) {
        // decide on text
        var sText = (piActiveCount==1) ? bm2_translations.messages.MSG_ITEMS_SINGULAR : bm2_translations.messages.MSG_ITEMS_PLURAL;
        var sString =  piActiveCount +' '+ sText;
        // update text
        oElement.innerHTML = sString;
        // animate open 
        if (oParent.style != 'block') {
            this.animateOpen(oParent);
        }
        // add eventListener to close button
        if (!this.bAlreadyUsedInfoBar) {
            this.bAlreadyUsedInfoBar = true;
            var oCloseBttn = document.getElementById('infoclose');
            YAHOO.util.Event.addListener(oCloseBttn, "click", this.closeInfoBar, this);
        }
    } else {
        // hide element
        if (oParent.style) {
            oParent.style.display = 'none';
        }
    }
}
// this is activated by eventListener on 'close' button in infoBar
// it closes the infoBar
YAHOO.bm2.selectBookmarks.prototype.closeInfoBar = function(e, obj) {
    // cancel out default action
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // loop through all checkboxes and turn on/off
    var aCheckBoxes = YAHOO.util.Dom.getElementsByClassName('chkbx', 'input', 'visiblebms');
    var iMaxLength = (aCheckBoxes.length>20) ? 20 : aCheckBoxes.length;
    for (var i=0; i<iMaxLength; i++) {
        if (aCheckBoxes[i].checked!=false) {
            obj.toggleCheckbox(aCheckBoxes[i], true, true);
        }
    }
    // update infobar
    obj.updateInfoBar(0);
    // update actions nav
    obj.updateActionsNav(0);
}
// this returns a reference to the InfoBar object
YAHOO.bm2.selectBookmarks.prototype.getInfoBar = function() {
    // if we have it & it's available, use it
    if (this.oInfoBar) 
        return this.oInfoBar;
    // if not, go get it (or return false)
    this.oInfoBar = document.getElementById(this.sInfoBarTextId);
    if (this.oInfoBar)
        return this.oInfoBar;
    else 
        return false;
}
// this returns a reference to the InfoBar span in an Actions Nav module
YAHOO.bm2.selectBookmarks.prototype.getInlineInfoBar = function() {
    // if we have it & it's available, use it
    if (this.oInlineInfoBar)
        return this.oInlineInfoBar;
    // if not, go get it (or return false)
    this.oInlineInfoBar = document.getElementById(this.sInlineInfoBarId);
    if (this.oInlineInfoBar)
        return this.oInlineInfoBar;
    else
        return false;
}
// when we toggle between Actions Nav modules, we need to clear
// previously grabbed objecs and grab fresh ones
YAHOO.bm2.selectBookmarks.prototype.clearInfoBars = function() {
    this.oInlineInfoBar = false;
    this.oInfoBar = false;
}
YAHOO.bm2.selectBookmarks.prototype.animateOpen = function(poObj) {
    if (!poObj || poObj.style.display=='block') return;
    // for some reason Safari doesn't animate, so just show it instead
    if (navigator.userAgent.indexOf('Safari')!=-1) {
        poObj.style.display = 'block';
        return;
    }
    // get height
    poObj.style.visibility = 'hidden';
    poObj.style.display = 'block';
    var sOldPos = poObj.style.position;
    poObj.style.position = 'absolute'; 
    var iHeight = poObj.offsetHeight;
    poObj.style.position = sOldPos;
    // animate
    poObj.style.height = 0;
    poObj.style.overflow = 'hidden';
    poObj.style.visibility = 'visible';
    var myAnim = new YAHOO.util.Anim(poObj, {height: { to: iHeight } }, .2 );
    myAnim.animate();
}


/* ACTIONS NAV INTERACTION */
// (for 'edit' and 'edit tags')
YAHOO.bm2.selectBookmarks.prototype.setActionsNav = function(poInlineActions) {
    if (poInlineActions) {
        this.bUseInlineActions = true;
        this.oInlineActions = poInlineActions
    }
}
YAHOO.bm2.selectBookmarks.prototype.updateActionsNav = function(piActiveCount) {
    if (this.bUseInlineActions) {
        this.oInlineActions.checkEditActuator(piActiveCount);
    }
}/* FOLDER TREE VIEW */
YAHOO.bm2.treeView = function (psFolder) {
    if (!psFolder || !document.getElementById) return;
    // set local vars
    this.onImage = "http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_icon_fldrPlusSign.gif";
    this.offImage = "http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_icon_fldrMinusSign.gif";
    // get reference to tree
    var oFolder = document.getElementById(psFolder);
    // get references to all expandable nodes
    var aExpNodes = YAHOO.util.Dom.getElementsByClassName('toggle', 'a', oFolder);
    for (var i=0; i<aExpNodes.length; i++) {
        YAHOO.util.Event.addListener(aExpNodes[i], "click", this.onExpand, this);
    }
    var aExpNodesOff = YAHOO.util.Dom.getElementsByClassName('toggleoff', 'a', oFolder);
    for (var i=0; i<aExpNodesOff.length; i++) {
        YAHOO.util.Event.addListener(aExpNodesOff[i], "click", this.onContract, this);
    }
}
YAHOO.bm2.treeView.prototype.onExpand = function (e, obj) {
    // remove default behaviour (go to href of link)
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    YAHOO.bm2.beacon('myfolders', 'exp');
    // swap out icon
    obj.toggleActuator(this, false);
    // get sub-lists
    obj.toggleList(this, false);
    // remove event listener, add opposit
    YAHOO.util.Event.removeListener(this, "click", obj.onExpand);
    YAHOO.util.Event.addListener(this, "click", obj.onContract, obj);
}
YAHOO.bm2.treeView.prototype.onContract = function(e, obj) {
    // remove default behaviour (go to href of link)
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    YAHOO.bm2.beacon('myfolders', 'col');
    // swap out icon
    obj.toggleActuator(this, true);
    // get sub-lists
    obj.toggleList(this, true);
    // remove event listener, add opposit
    YAHOO.util.Event.removeListener(this, "click", obj.onContract);
    YAHOO.util.Event.addListener(this, "click", obj.onExpand, obj);
}
YAHOO.bm2.treeView.prototype.toggleActuator = function(poAct, pbTrueFalse) {
    var aImage = poAct.getElementsByTagName('img');
    if (aImage.length>0 && aImage[0]) {
        aImage[0].src = (pbTrueFalse) ? this.onImage : this.offImage;
    }
}
YAHOO.bm2.treeView.prototype.toggleList = function(poThisObj, pbTrueFalse) {
    var oParent = poThisObj.parentNode;
    var aSubLists = oParent.getElementsByTagName('ul');
    if (aSubLists.length>0 && aSubLists[0]) {
        aSubLists[0].style.display = (pbTrueFalse) ? "none" : "block";
    }
    oParent.blur();
}/* FOLDER OPTIONS */
YAHOO.bm2.folderOptions = function () {
    // local vars
    this.sTagActId = 'changetmode';
    this.sFolderActId = 'changefmode';
    this.sTagsId = 'tags';
    this.sFoldersId = 'folders';
    this.sCookieName = 'ybm_liststyle';
    // add event listener to change to tagview link
    YAHOO.util.Event.addListener(this.sTagActId, "click", this.goToFolders, this);
    YAHOO.util.Event.addListener(this.sFolderActId, "click", this.goToTags, this);
}
YAHOO.bm2.folderOptions.prototype.goToTags = function(e, obj) {
    // cancel out default link
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // toggle module on/off
    obj.toggleView('tags');
    // tracking
    YAHOO.bm2.beacon('myfolders', 'usetags');
    // set cookie
    obj.setCookie('usetags');
}
YAHOO.bm2.folderOptions.prototype.goToFolders = function(e, obj) {
    // cancel out default link
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // toggle module on/off
    obj.toggleView('folders');
    // tracking
    YAHOO.bm2.beacon('tags', 'usefolders');
    // set cookie
    obj.setCookie('usefolders');
}
// changes the view
YAHOO.bm2.folderOptions.prototype.toggleView =function (psView) {
    var sOn  = (psView=='tags') ? this.sTagsId : this.sFoldersId;
    var sOff = (psView=='tags') ? this.sFoldersId : this.sTagsId;
    // get obj.
    var oOn = document.getElementById(sOn);
    var oOff = document.getElementById(sOff);
    oOn.style.display = 'block';
    oOff.style.display = 'none';
}
// set cookie
YAHOO.bm2.folderOptions.prototype.setCookie = function(psView) {
    // write a cookie with new name
    var nextyear = new Date();
    nextyear.setFullYear(nextyear.getFullYear() +1);

    // clear previous cookie
    var clearCookieStr = this.sCookieName +'='+ psView +'; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
    document.cookie = clearCookieStr;

    // set real cookie
    var cookieString = this.sCookieName +'='+ psView +'; path=/; domain=.bookmarks.yahoo.com; expires='+ nextyear.toGMTString();
    document.cookie = cookieString;
}





/* ADD FOLDER CANCEL OPTIONS */
YAHOO.bm2.addFolderCancel = function (psCancelBttnId) {
    this.oCancelBttn = document.getElementById(psCancelBttnId);
    YAHOO.util.Event.addListener(this.oCancelBttn, "click", this.cancelAction, this);
}
YAHOO.bm2.addFolderCancel.prototype.cancelAction = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // go back in history
    history.back();
}
/* VIEW OPTIONS */
// this changes the view when looking at your Bookmarks (full, grid, 1-line), etc
YAHOO.bm2.changeView = function (psActuatorId, psOptionsId) {
    // vars
    this.sSEC = 'actionbar';
    this.sCookieName = 'ybm_viewstyle';
    this.sOptionsId = 'viewoptions';
    this.sActuatorId = 'changeview';
    this.oBookmarkList;
    // create the menu
    this.bMenuExists = false;
    // add event listener to object
    var oActuator = document.getElementById(psActuatorId);
    oActuator.blur();
    YAHOO.util.Event.addListener(oActuator, "click", this.toggleOptions, this);
}
// onClick Handler
// toggles options menu on/off
// called by: event handler on actuator button
YAHOO.bm2.changeView.prototype.toggleOptions = function(e, obj) {
    // cancel out default link
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // remove focus
    if (this.blur) this.blur();
    // create menu first time around
    if (!obj.bMenuExists) {
        obj.bMenuExists = true;
        obj.createMenu();
    }
    // if still no menu, get outta here, something is wrong
    if (!obj.oMenu) {
        return;
    }
    YAHOO.util.Event.addListener(obj.oMenu, "click", obj.handleClick, obj);
    // animate open
    var bOnOff = (obj.oMenu.style.display=="block") ? true : false;
    // toggle
    obj.animate(bOnOff);
    // toggle any select boxes beneath for IE's sake
    obj.toggleSelect(bOnOff);
} 
YAHOO.bm2.changeView.prototype.createMenu = function() {
    // create menu
    this.oMenu = document.createElement('div');
    this.oMenu.id = this.sOptionsId;
    // create list
    var oList = document.createElement('ul');
    this.oMenu.appendChild(oList);
    // populate list
    oList.appendChild(this.createOption('large',   bm2_translations.messages.MSG_VIEW_FULL));
    oList.appendChild(this.createOption('details', bm2_translations.messages.MSG_VIEW_DETAILS));
    oList.appendChild(this.createOption('small',   bm2_translations.messages.MSG_VIEW_LIST));
    oList.appendChild(this.createOption('grid',    bm2_translations.messages.MSG_VIEW_GRID));
    // append element
    var oParent = document.getElementById('sortcntrl');
    oParent.appendChild(this.oMenu);
}
YAHOO.bm2.changeView.prototype.createOption = function(psClassName, psString) {
    // create list item
    var oListItem = document.createElement('li');
    // create link
    var oLink = document.createElement('a');
    oLink.href = '*';
    oLink.className = psClassName;
    oLink.innerHTML = psString;
    // attach and return
    oListItem.appendChild(oLink);
    return oListItem;
}
YAHOO.bm2.changeView.prototype.handleClick = function(e, obj) {
    // cancel out default link
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // figure out what link was clicked
    var oTarget = YAHOO.util.Event.getTarget(e); 
    while (oTarget.id != obj.sOptionsId) { 
          // are you a link?  if not, step up dom until we find one
          if (oTarget.nodeName.toUpperCase() == "A") { 
              // send className to set cookie and change view
              // send innerHTML to reset text inside actuator link
              obj.goToNewView(oTarget.className, oTarget.innerHTML);
              break; 
          } else { 
              oTarget = oTarget.parentNode; 
          } 
      } 
}
// changes the view
// called by links in the options menu
YAHOO.bm2.changeView.prototype.goToNewView = function(psStyle, psActText) {
    // figure out what view to use
    this.useTracking(psStyle);
    // make item invisible
    this.oMenu.style.display = 'none';
    // write a cookie with new name
    var nextyear = new Date();
    nextyear.setFullYear(nextyear.getFullYear() +1); 

    // clear previous cookie
    var clearCookieStr = this.sCookieName +"="+ psStyle;
    clearCookieStr += '; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
    document.cookie = clearCookieStr;

    // set real cookie
    var cookieString = this.sCookieName +"="+ psStyle;
    cookieString += "; path=/; domain=.bookmarks.yahoo.com; expires="+ nextyear.toGMTString();
    document.cookie = cookieString;

    // refresh page
    window.setTimeout('location.reload()', 50);
} 
YAHOO.bm2.changeView.prototype.toggleSelect = function(pbOnOff) {
    var oSelect = document.getElementById('mergeSelect');
    if (oSelect) {
        oSelect.style.visibility = (!pbOnOff) ? 'hidden' : 'visible';
    }
}

// HELPER FUNCTIONS
YAHOO.bm2.changeView.prototype.useTracking = function(psStyle) {
    // tracking
    var sSLK;
    var sSEC = 'actionbar';
    switch (psStyle) {
        case 'large':   sSLK = 'fullvw'; break;
        case 'details': sSLK = 'detailvw'; break;
        case 'small':   sSLK = 'listvw'; break;
        case 'grid':    sSLK = 'gridvw'; break;
    }
    YAHOO.bm2.beacon(sSEC, sSLK);
}
YAHOO.bm2.changeView.prototype.animate = function(pbClose) {
    if (!this.oMenu) return;
    if (pbClose) {
        this.oMenu.style.display = 'none';
        return;
    }
    // get height
    this.oMenu.style.visibility = 'hidden';
    this.oMenu.style.display = 'block';
    var sOldPos = this.oMenu.style.position;
    this.oMenu.style.position = 'absolute';
    this.oMenu.style.height = 'auto';
    var iHeight = this.oMenu.offsetHeight;
    this.oMenu.style.position = sOldPos;
    // clear vars and get heights
    this.oMenu.style.height = 0;
    this.oMenu.style.overflow = 'hidden';
    this.oMenu.style.visibility = 'visible';
    // animate
    var myAnim = new YAHOO.util.Anim(this.oMenu, {height: { from:0, to: iHeight } }, .2 );
    myAnim.animate();
}/* SUGGESTED TAGS */
YAHOO.bm2.suggestedTags = function () {

    var Evt = YAHOO.util.Event;
    var Dom = YAHOO.util.Dom;

    return {

        // set up local vars
        oACDataSrc: false,
        myAutoComp: false,
        sPageType: '',
        sOnColor: '',
        sActuator: '',
        oActuator: false,
        sTagsField: '',
        oTagsField: false,
        aSuggestedTags: [],
        bInitInputFields: false,
        iTagCounter: 0,

        // psActuator  -- the ID of the checkbox we're using as an actuator
        // psTagsField -- the ID of the element you want to toggle on/off
        // psOnColor   -- the color we use for active tag fields
        // psPageType  -- this is used on 'toolbar', 'inline', 'details', 'yq'
        init: function(psActuator, psTagsField, psOnColor, psPageType, poACDataSrc) {
            // set up local vars
            this.oACDataSrc = (poACDataSrc) ? new YAHOO.widget.DS_JSArray(poACDataSrc) : false;
            this.myAutoComp = [];
            this.sPageType = (psPageType) ? psPageType : 'inline';
            this.sOnColor = psOnColor;
            this.sActuator = 'addTags';
            this.oActuator = false;
            this.sTagsField = psTagsField;
            this.oTagsField = document.getElementById(this.sTagsField);
            this.aSuggestedTags;
            this.bInitInputFields = 0;
            // count number of existing tag-fields, so we can increment IDs properly
            this.iTagCounter = this.oTagsField.getElementsByTagName('input').length;
            // initialize actuator
            this.initActuator();
        },

        // attaches an event to the actuator -- when clicked, take user to toggleTags method
        initActuator: function () {
            // get actuator event
            this.oActuator = document.getElementById(this.sActuator);
            // if toolbar, resize on click
            this.resize(true);
            // add event listener to actuator object
            YAHOO.util.Event.addListener(this.oActuator, "click", this.toggleTags, this, true);
        },
        
        // if Tags are on via cookie, then turn on the module
        useTagsOnLoad: function() {
            // turn suggested tags on
            if (this.oActuator) {
                this.oActuator.checked = true;
                this.oTagsField.style.display = "block";
            };
            // initialize input fields
            if (this.oTagsField) {
                this.aSuggestedTags = this.oTagsField.getElementsByTagName('input');
                this.initInputFields();
                // resize
                this.resize(true);
            };
        },
        
        // turns on suggested tags, and moves cursor to first element
        toggleTags: function (e) {
            return;
            if (!this.oTagsField) return;
            // turn tags div on/off depending on whether this checkbox is checked or not
            this.oTagsField.style.display = (this.checked) ? "block" : "none";
            // if true, condition the suggestedTag fields
            if (this.checked) {
                // initialize input fields
                this.aSuggestedTags = this.oTagsField.getElementsByTagName('input');
                this.initInputFields();
                // move focus to first field
                if (this.aSuggestedTags.length >0) this.moveToTag(0);
            };
            // resize
            this.resize(false);
            // save a cookie
            var nextyear = new Date();
            nextyear.setFullYear(nextyear.getFullYear() +1);
            // clear previous cookie
            var clearCookieStr = 'ybm_useTags' +'='+ this.checked +'; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
            document.cookie = clearCookieStr;
            // set real cookie
            var cookieString = 'ybm_useTags' +'='+ this.checked +'; path=/; domain=.bookmarks.yahoo.com; expires='+ nextyear.toGMTString();
            document.cookie = cookieString;
        },
        
        // adds required event listeners to input fields 
        // also adds autocomplete goodness
        initInputFields: function() {
            // we only want to initialize this once
            if (this.bInitInputFields) 
                return;
            this.bInitInputFields = 1;
            // loop through all fields and add event handlers to them
            for (var i=0; i < this.aSuggestedTags.length; i++) {
                // add Delete fields to all input fields that have content
                if (this.aSuggestedTags[i].value!='') {
                    this.addDeleteLink(this.aSuggestedTags[i]);
                };
                // add required event listeners to fields
                YAHOO.util.Event.addListener(this.aSuggestedTags[i], "focus", this.fixZIndex, this);
                YAHOO.util.Event.addListener(this.aSuggestedTags[i], "focus", this.highlightTag, this);
                YAHOO.util.Event.addListener(this.aSuggestedTags[i], "keyup", this.checkForContent, this);
                YAHOO.util.Event.addListener(this.aSuggestedTags[i], "keypress", this.cancelEnterKey, this);
                // add autosuggest
                this.initAC(i);
            };
            // add event listener to last input field (to add another input box if user starts typing here)
            var iLastInputIndex = this.aSuggestedTags.length-1;
            YAHOO.util.Event.addListener(this.aSuggestedTags[iLastInputIndex], "keyup", this.checkForLast, this);
        },
        
        initAC: function(piIndex) {
            if (!this.oACDataSrc) return;
            this.myAutoComp[piIndex] = new YAHOO.widget.AutoComplete("addTags"+piIndex, "actags"+piIndex, this.oACDataSrc); 
            this.myAutoComp[piIndex].animVert = true;
            this.myAutoComp[piIndex].animSpeed = .2;  
            this.myAutoComp[piIndex].maxResultsDisplayed = 4; 
            this.myAutoComp[piIndex].minQueryLength = 1;
            this.myAutoComp[piIndex].queryDelay = 0;
            this.myAutoComp[piIndex].typeAhead = false; 
            this.myAutoComp[piIndex].allowBrowserAutocomplete = false; 
        },
        
        addDeleteLink: function(poThisInput) {
            // make sure we don't have one already
            var oParentNode = poThisInput.parentNode;
            var aDeleteNodes =  YAHOO.util.Dom.getElementsByClassName('delete', 'a', oParentNode);
            if (aDeleteNodes && aDeleteNodes.length>0) return;
            // create new delete element
            var oNewLink = document.createElement('a');
            oNewLink.className = "delete";
            oNewLink.innerHTML = '<em>'+ bm2_translations.messages.MSG_NAV_DELETE+'</em>';
            oNewLink.title = bm2_translations.messages.MSG_NAV_DELETE;
            oNewLink.action = false;
            // add behind current current input
            oParentNode.appendChild(oNewLink);
            // add event handler to delete
            YAHOO.util.Event.addListener(oNewLink, "click", this.deleteTag, this);
        },
        
        // removes the delete node
        removeDeleteLink: function(poParentNode, poDeleteNode) {
            poParentNode.removeChild(poDeleteNode);
        },
        
        // clears input field (user has just clicked Delete X)
        // called by event listener, added in "addDeleteLink"
        // NOTE: NOT USED IN THIS VERSION, USING "deleteTag" INSTEAD!!!
        clearInput: function(e) {
            // get input node
            var oParentDiv = this.parentNode;
            var aInputFields = oParentDiv.getElementsByTagName('input');
            // if input node, clear value and assign focus
            if (aInputFields[0]) {
                aInputFields[0].value="";
                aInputFields[0].focus();
            };
            // remove delete node
            this.removeDeleteLink(oParentDiv, this);
        },
        
        // clears input field (ALT METHOD FOR ABOVE)
        deleteTag: function(e) {
            // get input node & remove from page
            var oParentDiv = this.parentNode;
            var oTagsField = oParentDiv.parentNode;
            oTagsField.removeChild(oParentDiv);
            // reset suggested Tags array
            this.aSuggestedTags = this.oTagsField.getElementsByTagName('input');
            var iTagsLength = this.aSuggestedTags.length;
            var iNeedMore = 5-this.aSuggestedTags.length;
            // top up list to minimum of five
            for (var i=1; i<=iNeedMore; i++) {
                // remove event listener from current last node
                YAHOO.util.Event.removeListener(this.aSuggestedTags[iTagsLength-1], "keyup", this.checkForLast);
                // create new node & add to page & aSuggestedTags array
                var oNewNode = this.createNewTag(oTagsField);
                // iterate
                iTagsLength++;
            };
            this.aSuggestedTags = this.oTagsField.getElementsByTagName('input');
            // move carat to first open tag
            for (i=0; i<iTagsLength; i++) {
                if (!this.aSuggestedTags[i].value) {
                    this.moveToTag(i);
                    break;
                };
            };
            // if toolbar, resize on click
            this.resize(false);
        },
        
        moveToTag: function(piIndex) {
            this.aSuggestedTags[piIndex].focus();
        },
        
        highlightTag: function(e, obj) {
            // change color and select
            this.style.color = obj.sOnColor;
            this.select();
            // remove listener
            YAHOO.util.Event.removeListener(this, "focus", obj.highlightTag);
        },
        
        // run each time user types in tag entry box
        // if no value, remove delete node; otherwise, add one
        checkForContent: function(e, obj) {
            // check for content
            if (!this.value) {
                var oParentNode = this.parentNode;
                var aDeleteNodes = oParentNode.getElementsByTagName('a');
                // if field is empty, remove any delete tags
                if (aDeleteNodes && aDeleteNodes.length>0) {
                    obj.removeDeleteLink(oParentNode, aDeleteNodes[0]);
                };
            } else {
                // if field has content, add a delete tag
                obj.addDeleteLink(this);
            };
        },
        
        // checks to see if the last suggested tag node is full,
        // if so -- create a new blank one
        checkForLast: function(e, obj) {
            // if this field is NOT empty, then add another input field
            if (this.value!='') {
                // remove event listener 
                YAHOO.util.Event.removeListener(this, "keyup", obj.checkForLast);
                // create new node & add to page
                var oNewNode = obj.createNewTag(obj.oTagsField);
                // if toolbar, resize on click
                obj.resize(false, 'newNode');
            };
        },
       
        // creates a new node 
        createNewTag: function(poObjToAppend) {
            // create input node
            var oNewInput = document.createElement('input');
            oNewInput.type = "text";
            oNewInput.style.color = this.sOnColor;
            oNewInput.className = "suggestedtag";
            oNewInput.name = "tag[]";
            oNewInput.id = "addTags"+ this.iTagCounter;
            YAHOO.util.Event.addListener(oNewInput, "focus", this.fixZIndex, this);
            // add autosuggest
            var oNewAC = document.createElement('div');
            oNewAC.className = 'actags';
            oNewAC.id = 'actags'+ this.iTagCounter;
            // wrap input in a div
            var oNewNode = document.createElement('div');
            oNewNode.className = 'tagwrap';
            oNewNode.style.zIndex = 1000;
            oNewNode.appendChild(oNewInput);
            oNewNode.appendChild(oNewAC);
            poObjToAppend.appendChild(oNewNode)
            // add event listeners to new element
            YAHOO.util.Event.addListener(oNewInput, "keyup", this.checkForLast, this);
            YAHOO.util.Event.addListener(oNewInput, "keyup", this.checkForContent, this);
            YAHOO.util.Event.addListener(oNewInput, "keypress", this.cancelEnterKey, this);
            this.initAC(this.iTagCounter);
            // increment counter
            this.iTagCounter++;
            // return object
            return oNewNode;
        },

        // resizes upon each additional form field
        resize: function(pbOnInit, psMode) {
            if (this.sPageType=='details') {
                // if details page
                return;
            } else if (this.sPageType=='yq') {
                if (pbOnInit ) return;
                window.scrollTo(0,1000)
            } else if (this.sPageType=='toolbar') {
                // if toolbar
                if (window.external) { 
                    tbResize(); 
                    return;
                };
            } else if (this.sPageType=='inline') {
                if (pbOnInit ) return;
                // if inline
                var oInlineEditObj = document.getElementById('inlineactions');
                var oInnerContent = document.getElementById('innerContent');
                if (oInlineEditObj && oInnerContent) {
                    var iNewHeight = oInnerContent.offsetHeight;
                    oInlineEditObj.style.height = parseInt(iNewHeight) + 10 + 'px'; 
                };
            };
        },
        
        // cancel out enterkey
        cancelEnterKey: function (e, obj) {
            if (e.keyCode==13) {
                if (e.preventDefault) e.preventDefault();
                else e.returnValue = false;
            };
        },
        
        // gets all div wrappers for suggested tags
        fixZIndex: function (e, obj) {
            if (!obj.oTagParent) obj.oTagParent = document.getElementById('tagfields');
            if (!obj.oTagParent) return;
            // get child nodes
            var aWrappers = YAHOO.util.Dom.getElementsByClassName('tagwrap', 'div', this.oTagParent);
            for (var i=0; i<aWrappers.length; i++) {
                if (aWrappers[i]==this.parentNode)  {
                    aWrappers[i].style.zIndex = 2000;
                } else {
                    aWrappers[i].style.zIndex = 1000;
                };
            };
        },

        EOF: null
    }
}();/* CLEARS FORM FIELDS OF DEFAULT VALUES ON FOCUS */
// psElements - array of objects to attach Listener to
YAHOO.bm2.saveBM = function (psElements, psOnColor, psOffColor) {
  // local vars
  this.onColor = psOnColor;
        this.offColor = psOffColor;
  var ids = [];
  // get elements to attach events to
  if (!psElements || !psElements.length>0) { return; }
  for (var i=0; i<psElements.length; i++) {
    ids[i] = document.getElementById(psElements[i]);
    if (ids[i]) {
        ids[i].style.color = this.offColor;
    }
  };
  // add event handlers
  YAHOO.util.Event.addListener(ids, "focus", this.clickInput, this);
};
// clears the form itself
YAHOO.bm2.saveBM.prototype.clickInput = function (e, obj) {
  // force focus
  this.focus();
  // remove text
  this.value = "";
  this.style.color = obj.onColor;
  // remove listener
  YAHOO.util.Event.removeListener(this, "focus", obj.clickInput);
};/* IM from list 
YAHOO.bm2.setIMBuddy = function() {
    var oInput = document.getElementById('addIM');
    var oSelect = document.getElementById('buddy');
    var oText = document.getElementById('msgIM');
    if (oInput.value != '') {
        oInput.value = oSelect.value;
        oInput.style.color = "#333";
        oSelect.selectedIndex = 0;
        if (oText) oText.focus();
    }
}


/* EMAIL Auto-complete 
YAHOO.bm2.email = function() {
    AC_targetElements = [ "remail" ];
    AC_insertEmailsOnly = true;
    AC_ignoreLists = true;
    // script nodes
    this.sScriptDataSrc = 'http://address.mail.yahoo.com/acjs3/utf8/us/';
    var sDataSrcId = 'userDataPath';
    var oDataSrc = document.getElementById(sDataSrcId);
    if (oDataSrc && oDataSrc.innerHTML!='') {
        this.sScriptDataSrc += oDataSrc.innerHTML;
    }
    // add script nodes
    this.sScriptDataId = 'scriptdata'
    this.addNode(this.sScriptDataSrc, this.sScriptDataId);
    this.addNode('/js/data.js', this.sScriptDataId);
    // initialize once above scriptnode has been added
    this.doDelay = true;
    this.waitForData(50);
}
YAHOO.bm2.email.prototype.waitForData = function(piDelay) {
    YAHOO.bm2.thisEmailAC = this;
    try {
        if(AC_allCanons) {
            this.doDelay = false;
            AC_OnLoad();
              window.setTimeout('testObj()', 4000);
        }
    } catch(err) {
        if (this.doDelay) {
            this.delay(piDelay);
        }
    }
}
testObj = function() {
    var aTemp =  YAHOO.util.Dom.getElementsByClassName('ac_menu', 'div', document.body);
    var oParent;
    var tempObj;
    for (i in aTemp) {
       tempObj = document.getElementById('bookmarks');
       oParent = aTemp[i].parentNode;
    }
}
YAHOO.bm2.email.prototype.delay = function(piDelay) {
    piDelay *= 2;
    window.setTimeout('YAHOO.bm2.thisEmailAC.waitForData("'+piDelay+'")', piDelay);
}
YAHOO.bm2.email.prototype.addNode = function(psSRC, psID) {
    // check if node already exists
    var oIsNode = document.getElementById(psID);
    if (oIsNode) return;
    // create node
    var oNode = document.createElement('script');
    oNode.language = 'javascript';
    oNode.type = 'text/javascript';
    oNode.src = psSRC;
    oNode.id = psID;
    // append to head
    document.getElementsByTagName('head')[0].appendChild(oNode);
}


/* IM send object 
YAHOO.bm2.send = function(poInlineActions) {
    this.sActIMId = 'imsubmit';
    this.sCancelIMId = 'imcancel';
    this.sBuddyId = 'addIM';
    this.sMsgId = 'msgIM';
    this.oInlineActions = poInlineActions;
    // initialize
    this.init();
}
YAHOO.bm2.send.prototype.init = function() {
    // add event listeners to submit buttons
    this.oActIM = Dom.get(this.sActIMId);
    Evt.on(this.oActIM, "click", this.submitForm, this);
    // add event listeners to cancel buttons
    this.oCancelIM = Dom.get(this.sCancelIMId);
    Evt.on(this.oCancelIM, "click", this.oInlineActions.close, this.oInlineActions);
}
YAHOO.bm2.send.prototype.submitForm = function(e, obj) {
    // prevent default
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    YAHOO.bm2.beacon('action', 'im');
    // get data
    var oBuddy = Dom.get(obj.sBuddyId);
    obj.sBuddy = obj.formatText(oBuddy.value);
    var oMessage = Dom.get(obj.sMsgId);
    obj.sMessage = obj.formatText(oMessage.value);
    obj.sMessage = obj.sMessage.replace(/%0D/g, ' ');
    oIFrame = obj.getIFrame();
    // send message
    if (obj.sBuddy && obj.sMessage) {
        oIFrame.src = 'ymsgr:im?to='+ obj.sBuddy +'&msg='+ obj.sMessage;
    }
}
YAHOO.bm2.send.prototype.getIFrame = function() {
    if (this.oIFrame) return this.oIFrame;
    // create and append a new iFrame
    this.oIFrame = document.createElement('iframe');
    this.oIFrame.style.visibility = 'hidden';
    this.oIFrame.style.position = 'absolute';
    this.oIFrame.style.left = '-2000px';
    this.oIFrame.style.height = '1px';
    this.oIFrame.style.width = '1px';
    document.body.appendChild(this.oIFrame);
    return this.oIFrame;
}
YAHOO.bm2.send.prototype.formatText = function(psText) {
    return encodeURIComponent(psText);
}
/* EDIT TAGS */
// this object keeps tabs on what bookmarks are checked/unchecked
// and adds them to the "edit tags" module dynamically (if they're
// toggled after the module is open)
YAHOO.bm2.editTags = function(poInlineActions) {
    // set up vars
    this.oInlineActions = poInlineActions;
    this.sFormId = 'actionsform';
    this.sBookmarkListId = 'visiblebms';
    this.sCheckBoxClassName = 'chkbx';
    this.sTagsClassName = 'tags';
    this.sCheckBoxIdPrefix = 'selectBM';
    this.sSelectId = 'mergeSelect';
    this.sTagAddId = 'tagadd';
    this.sAddBttnId = 'addbttn';
    this.sDelBttnId = 'delbttn';
    this.sFinishBttnId = 'finishbttn';
    this.sOrigAddTagVal = document.getElementById(this.sTagAddId).value;
    // arrays of data to add, remove
    this.aAdd = [];
    this.aDel = [];
    // initialize
    this.init();
}
YAHOO.bm2.editTags.prototype.purge = function() {
    // checkboxes
    this.aCheckBoxes = this.getCheckBoxes();
    if (this.aCheckBoxes && this.aCheckBoxes.length>0)
        YAHOO.util.Event.removeListener(this.aCheckBoxes, "click", this.selection, this);
    // submit bttns
    this.oAdd = document.getElementById(this.sAddBttnId);
    if (this.oAdd) 
        YAHOO.util.Event.removeListener(this.oAdd, "click", this.actionAdd, this);
    this.oDel = document.getElementById(this.sDelBttnId);
    if (this.oDel)
        YAHOO.util.Event.addListener(this.oDel, "click", this.actionDel, this);
    this.oFinish = document.getElementById(this.sFinishBttnId);
    if (this.oFinish)
        YAHOO.util.Event.addListener(this.oFinish, "click", this.actionFinish, this);
}
YAHOO.bm2.editTags.prototype.init = function() {
    // checkboxes
    this.aCheckBoxes = this.getCheckBoxes();
    YAHOO.util.Event.addListener(this.aCheckBoxes, "click", this.selection, this);
    // submit bttns
    this.oAdd = document.getElementById(this.sAddBttnId);
    YAHOO.util.Event.addListener(this.oAdd, "click", this.actionAdd, this);
    this.oDel = document.getElementById(this.sDelBttnId);
    YAHOO.util.Event.addListener(this.oDel, "click", this.actionDel, this);
    this.oFinish = document.getElementById(this.sFinishBttnId);
    YAHOO.util.Event.addListener(this.oFinish, "click", this.actionFinish, this);
}
// toggle checkboxes
YAHOO.bm2.editTags.prototype.selection = function(e, obj) {
    var bOnOff = (this.checked) ? true : false;
    if (bOnOff) {
        obj.addToField(this);
    } else {
        obj.delFromField(this);
    }
}
YAHOO.bm2.editTags.prototype.actionAdd = function(e, obj) {
    var oInput, sTag, aOptions, bMatch, i;
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;

    // get add value
    oInput = document.getElementById(obj.sTagAddId);
    if (!oInput) return;
    sTag = oInput.value;

    // if they haven't typed anything in, just ignore
    if (obj.sOrigAddTagVal == sTag) {
        return;
    };

    // tracking
    YAHOO.bm2.beacon('action', 'addtags');
    // put in array
    obj.clearFromArray(obj.aDel, sTag);
    if (sTag)
        obj.aAdd.push(sTag);
    // clear input
    oInput.value = '';
    oInput.focus();
    // add to list
    aOptions = obj.getCurrentItems();
    bMatch = false;
    for (i=0; i<aOptions.length; i++) {
        if (aOptions[i]==sTag) {
            bMatch = true;
            break;
        }
    }
    // add to list if you didn't find
    if (!bMatch) {
        aOptions.push(sTag);
        aOptions.sort();
        obj.redrawList(aOptions);
    }
}
YAHOO.bm2.editTags.prototype.actionDel = function(e, obj) {
    var oSelect, aCurrentItems, sTag, i;
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    YAHOO.bm2.beacon('action', 'deltags');
    // get delete value 
    oSelect = document.getElementById(obj.sSelectId);
    if (!oSelect) return;
    aCurrentItems = oSelect.getElementsByTagName('option');
    sTag = '';
    for (i=0; i<aCurrentItems.length; i++) {
        if (aCurrentItems[i].selected) {
            sTag = aCurrentItems[i].innerHTML;
            oSelect.removeChild(aCurrentItems[i]);
        }
    }
    // put in array
    obj.clearFromArray(obj.aAdd, sTag);
    if (sTag)
       obj.aDel.push(sTag);
}
YAHOO.bm2.editTags.prototype.actionFinish = function(e, obj) {
    var oForm, oInput, i;
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get form obj
    oForm = document.getElementById(obj.sFormId);
    // add form elements
    oInput = obj.createInput('isMultipleEdits', 'true');
    oForm.appendChild(oInput);
    oInput = obj.createInput('adminEditAction', 'Finish');
    oForm.appendChild(oInput);
    for (i=0; i<obj.aDel.length; i++) {
        oInput = obj.createInput('rtag[]', obj.aDel[i]);
        oForm.appendChild(oInput);
    }
    for (i=0; i<obj.aAdd.length; i++) {
        oInput = obj.createInput('tag[]', obj.aAdd[i]);
        oForm.appendChild(oInput);
    }
    // submit form through inlineactions object
    obj.oInlineActions.submitForm(e, obj.oInlineActions);
}
YAHOO.bm2.editTags.prototype.createInput = function(psName, psValue) {
    var oInput = document.createElement('input');
    oInput.type = 'hidden';
    oInput.name = psName;
    oInput.value = psValue;
    return oInput;
}



// removes from array
YAHOO.bm2.editTags.prototype.clearFromArray = function(pArray, psTag) {
    for (var i=0; i<pArray.length; i++) {
        if (pArray[i]==psTag) {
            pArray.splice(i,1);
        }
    } 
}
// get checkboxes
YAHOO.bm2.editTags.prototype.getCheckBoxes = function() {
    var aCheckBoxes = YAHOO.util.Dom.getElementsByClassName(this.sCheckBoxClassName, 'input', this.sBookmarkListId);
    return aCheckBoxes;
}
// get tags from all checkboxes
YAHOO.bm2.editTags.prototype.getAllCheckedTags = function() {
    var aCheckBoxes, aActiveTags, aNewTags, aReturnTags;
    // get checkboxes
    aCheckBoxes = this.getCheckBoxes();
    // loop through checkboxes for active items
    aActiveTags = [];
    aNewTags = [];
    for (i=0; i<aCheckBoxes.length; i++) {
        if (aCheckBoxes[i].checked) {
            aNewTags = this.getTags(aCheckBoxes[i].id);
            aActiveTags = aActiveTags.concat(aNewTags);
        }
    }
    // remove dupes
    aActiveTags.sort();
    aReturnTags = [];
    for (i=0; i<aActiveTags.length; i++) {
        if (i==0 || aActiveTags[i]!=aActiveTags[i-1]) {
            aReturnTags.push(aActiveTags[i]);
        }
    }
    // return
    return aReturnTags;
}
// gets tags out of bookmark item
YAHOO.bm2.editTags.prototype.getTags = function(psId) {
    var sId, aTagObj, aTagsNames, aTags, i;
    if (psId.length<=this.sCheckBoxIdPrefix.length) return;
    // get id
    sId = psId.substr(this.sCheckBoxIdPrefix.length);
    // get tag obj
    aTagObj = YAHOO.util.Dom.getElementsByClassName(this.sTagsClassName, 'strong', sId);
    if (aTagObj[0]) {
        // get tags 
        aTagsNames = aTagObj[0].getElementsByTagName('a');
        aTags = [];
        for (i=0; i<aTagsNames.length; i++) {
            aTags.push(aTagsNames[i].innerHTML);
        }
        aTags.sort();
        return aTags;
    } else { 
        return [];
    }
}
// gets options in the current select box
YAHOO.bm2.editTags.prototype.getCurrentItems = function() {
    var oSelect, aCurrentItems, aOptions, i;
    oSelect = document.getElementById(this.sSelectId);
    if (!oSelect) return false;
    aOptions = [];
    aCurrentItems = oSelect.getElementsByTagName('option');
    if (!aCurrentItems || aCurrentItems.length==0) return aOptions;
    for (i=0; i<aCurrentItems.length; i++) {
        aOptions.push(aCurrentItems[i].innerHTML);
    }
    return aOptions;
}
YAHOO.bm2.editTags.prototype.removeDelTags = function(paTags) {
    // del tags
    for (i=0; i<this.aDel.length; i++) {
        for (ii=0; ii<paTags.length; ii++) {
            if (this.aDel[i]==paTags[ii]) {
                paTags.splice(ii, 1);
            }
        }
    }
}


/* add/remove from field */
YAHOO.bm2.editTags.prototype.delFromField  = function(paTags) {
    var aCurrentTags, i;
    // loop through current tags and see if they should be added
    aCurrentTags = this.getAllCheckedTags();
    aCurrentTags = aCurrentTags.concat(this.aAdd);
    this.removeDelTags(aCurrentTags);
    // redraw
    aCurrentTags.sort();
    this.redrawList(aCurrentTags);
}
YAHOO.bm2.editTags.prototype.addToField  = function(poAct) {
    var aTags, aOptions, bMatch, bMatches, i, ii;
    // get tags to del
    aTags = this.getTags(poAct.id);
    // loop through tags and see if they should be added
    aOptions = this.getCurrentItems();
    aMatches = []; 
    for (i=0; i<aTags.length; i++) {
        // loop through each current tag
        bMatch = false;
        for (ii=0; ii<aOptions.length; ii++) {
            // if you find a match, break the loop
            if (aOptions[ii]==aTags[i]) {
                bMatch = true;
                break;
            }
        }
        // add to list if you didn't find
        if (!bMatch) aOptions.push(aTags[i]);
    }
    this.removeDelTags(aOptions);
    aOptions.sort();
    this.redrawList(aOptions);
}
YAHOO.bm2.editTags.prototype.redrawList = function(paOptions) {
    var oSelect, oNewOption, i;
    // get list obj
    oSelect = document.getElementById(this.sSelectId);
    if (!oSelect) return;
    // clear obj
    oSelect.innerHTML = '';
    // add new elements
    oNewOption;
    for (i=0; i<paOptions.length; i++) {
        oNewOption = document.createElement('option');
        oNewOption.value = paOptions[i];
        oNewOption.innerHTML = paOptions[i];
        oSelect.appendChild(oNewOption);
    }
}
/* IE tour */
YAHOO.bm2.ieTour = function() {
    // get element IDs
    this.sStep1ID = 'tourstep1';
    this.sStep2ID = 'tourstep2';
    this.sStep3ID = 'tourstep3';
    this.sStartBttn = 'promostartlink';
    this.sTourID = 'ietour';
    this.sBackgroundID = 'ietourbg';
    this.sFrameID = 'ieframe';
    this.sWindowID = 'iewindow';
    // add eventListener
    this.oTour = Dom.get(this.sTourID);
    Evt.on(this.oTour, "click", this.onClick, this);
    this.oStartBttn = Dom.get(this.sStartBttn);
    Evt.purgeElement(this.oStartBttn);
    Evt.on(this.oStartBttn, 'click', this.onStartClick, this);
}
YAHOO.bm2.ieTour.prototype.onClick = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get target area
    var oTarget = YAHOO.util.Event.getTarget(e);
    if (oTarget.blur)
        oTarget.blur();
    if (oTarget.id==obj.sStep1ID || oTarget.id==obj.sStep2ID || oTarget.id==obj.sStep3ID) {
        obj.launch(oTarget.id);
    }
}
YAHOO.bm2.ieTour.prototype.onStartClick = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get target area
    obj.launch('tourstep1');
}
YAHOO.bm2.ieTour.prototype.launch = function(psID) {
    // handle background
    this.createBackground();
    // launch window
    this.createWindow(psID);
}
YAHOO.bm2.ieTour.prototype.createWindow = function(psID) {
    // get positioning
    var iWidth = 320;
    var iHeight = 356;
    var iLeft = (Dom.getViewportWidth() > iWidth) ? (Dom.getViewportWidth()-iWidth)/2 : 0;
    var iTop = (Dom.getViewportHeight() > iWidth) ? (Dom.getViewportHeight()-iWidth)/2: 0;
    // create window
    this.oFrame = document.createElement('div');
    this.oFrame.style.width = iWidth +'px';
    this.oFrame.style.height = iHeight +'px';
    this.oFrame.style.left = iLeft +'px';
    this.oFrame.style.top = iTop +'px';
    this.oFrame.style.border = '2px solid white';
    this.oFrame.id = this.sFrameID;
    // create window
    this.oWindow = document.createElement('iframe');
    this.oWindow.style.width = '100%';
    this.oWindow.style.height = '100%';
    if (psID == 'tourstep2') {
        this.oWindow.src = '/toolbar/ieimport';
	} else if (psID == 'tourstep3') {
        this.oWindow.src = '/help/step3';	
    } else if (psID == 'tourstep4') {
        this.oWindow.src = '/help/step4';
    } else {
        this.oWindow.src = '/help/step1';
    }
    this.oWindow.id = this.sWindowID;
    // attach
    this.oFrame.appendChild(this.oWindow);
    document.body.appendChild(this.oFrame);
}
YAHOO.bm2.ieTour.prototype.createBackground = function() {
    // get dimensions
    var iDocHeight = Dom.get('ybmdoc').offsetHeight + Dom.get('windowshade').offsetHeight + Dom.get('ybmft').offsetHeight;
    var iHeight = (iDocHeight > Dom.getViewportHeight()) ? iDocHeight : Dom.getViewportHeight();
    var iWidth  = Dom.getViewportWidth();
    // grey out background
    this.oBackground = document.createElement('div');
    this.oBackground.id = this.sBackgroundID;
    this.oBackground.style.height = iHeight +'px';
    this.oBackground.style.width = iWidth +'px';
    document.body.appendChild(this.oBackground);
}


/* windowshade stuff */
YAHOO.bm2.promo = function (psCookieName) {
    var i;
    this.sCookieName = psCookieName;
    this.sPromoId = 'windowshade';
    this.sBttnId = 'promobutton';
    this.sCloseId = 'promocloselink';
    this.sStartId = 'promostartlink';
    this.sCookiePrefix = 'ybm_';
    // display promo module
    this.oPromo = document.getElementById(this.sPromoId);
    this.oPromo.style.display = 'block';
    // margin out the top
    this.oDoc = document.getElementById('ybmdoc');
    // get close buttons
    this.oCloseBttn = document.getElementById(this.sCloseId);
    this.oStartBttn = document.getElementById(this.sStartId);
    // add event listeners	
    YAHOO.util.Event.addListener(this.oCloseBttn, "click", this.closeMod, this);
    YAHOO.util.Event.addListener(this.oStartBttn, "click", this.closeMod, this);
}

YAHOO.bm2.promo.prototype.openMod  = function(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get target area
    var oTarget = YAHOO.util.Event.getTarget(e);
    if (oTarget.blur)
        oTarget.blur();
    if (oTarget.id==obj.sStep1ID || oTarget.id==obj.sStep2ID || oTarget.id==obj.sStep3ID) {
        obj.launch(oTarget.id, oTarget);
    }
}

YAHOO.bm2.promo.prototype.closeMod = function (e, obj) {
    // cancel out default submit
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // close module
    if (obj.oPromo) {
        obj.oPromo.style.display = 'none';
    }
    if (obj.oDoc)
        obj.oDoc.style.marginTop = '0px';
    // save cookie off
    var nextyear = new Date();
    nextyear.setFullYear(nextyear.getFullYear() +1);
    // clear previous cookie
    var clearCookieStr = obj.sCookiePrefix + obj.sCookieName +"="+ true;
    clearCookieStr += '; path=/; expires=Fri, 02-Jan-1970 00:00:00 GMT';
    document.cookie = clearCookieStr;
    // set new cookie
    var cookieString = obj.sCookiePrefix + obj.sCookieName +"="+ true;
    cookieString += "; path=/; domain=.bookmarks.yahoo.com; expires="+ nextyear.toGMTString();
    document.cookie = cookieString;
}

/* handle recommendations */
YAHOO.bm2.recommendations = function (psCurrentOption) {
    // local vars
    this.sActId = 'aclact';
    this.sDGId = 'visible';
    this.sChoicesId = 'choices';
    this.sCurrentOption = psCurrentOption;
    this.bKeepShowing = false;
    // add event listener to actuator
    this.oAct = document.getElementById(this.sActId);
    if (!this.oAct) return;
    YAHOO.util.Event.addListener(this.oAct, "click", this.displayChoices, this);
    // add event listeners to 'contact' choices
    this.oContactOptions = document.getElementById('optioncontacts');
    this.aContacts = this.oContactOptions.getElementsByTagName('input');
    YAHOO.util.Event.addListener(this.aContacts, "click", this.maintainOneOption, this);
}   
// one checkbox has to ALWAYS be on
// otherwise submit will fail
// this turns on another option if both are unchecked
YAHOO.bm2.recommendations.prototype.maintainOneOption = function(e, obj) {
    var bAreOpen = 0;
    var oOtherOption;
    for (var i=0; i<obj.aContacts.length; i++) {
        if (obj.aContacts[i].checked)
           bAreOpen++;
        if (obj.aContacts[i] != this)
           oOtherOption = obj.aContacts[i] ;
    }
    if (!bAreOpen) {
        oOtherOption.click();
    }
}
YAHOO.bm2.recommendations.prototype.displayChoices = function(e, obj) {
    // prevent default from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // make actuator invisible
    obj.oChoice = this.parentNode;
    if (obj.oChoice) obj.oChoice.style.display = 'none';
    // turn on choices
    obj.oChoices = document.getElementById(obj.sChoicesId);
    if (!obj.oChoices) return;
    obj.oChoices.style.display = 'block';
    YAHOO.util.Event.purgeElement(obj.oChoices);
    YAHOO.util.Event.addListener(obj.oChoices, "mouseout", obj.forceOpenOff, obj);
    YAHOO.util.Event.addListener(obj.oChoices, "mouseover", obj.forceOpen, obj);
    // add event listeners to choices
    var aLinks = obj.oChoices.getElementsByTagName('a');
    if (aLinks && aLinks.length>0) {
        YAHOO.util.Event.removeListener(aLinks, "click", obj.makeSelection, obj);
        YAHOO.util.Event.addListener(aLinks, "click", obj.makeSelection, obj);
    }
    // add listener to body
    thisRec = obj;
    window.setTimeout('thisRec.addListener()', 100);
}
YAHOO.bm2.recommendations.prototype.addListener = function() {
    // add event listener to body, to close options if offclick
    YAHOO.util.Event.removeListener(document, 'mousedown', this.close, this);
    YAHOO.util.Event.addListener(document, 'mousedown', this.close, this);
}
YAHOO.bm2.recommendations.prototype.forceOpen = function (e, obj) {
    obj.bKeepShowing = true;
}
YAHOO.bm2.recommendations.prototype.forceOpenOff = function (e, obj) {
    obj.bKeepShowing = false;
}
YAHOO.bm2.recommendations.prototype.close = function (e, obj) {
    if (obj.bKeepShowing)  {
        obj.bKeepShowing = false;
        return;
    }
    YAHOO.util.Event.removeListener(document, 'mousedown', obj.close); 
    obj.hideChoices();
}
YAHOO.bm2.recommendations.prototype.hideChoices = function () {
    if (!this.oChoice || !this.oChoices) return;
    this.oChoices.style.display = 'none';
    this.oChoice.style.display = 'block';
}
YAHOO.bm2.recommendations.prototype.makeSelection = function(e, obj) {
    // prevent default from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // make selection
    var sText = this.innerHTML;
    var sClass = this.className;
    obj.storeData(sClass, sText);
    // swap choices/choice
    obj.hideChoices();
}
YAHOO.bm2.recommendations.prototype.storeData = function(psClass, psText) {
    // change actuator link
    this.oAct.className = psClass;
    this.oAct.innerHTML = psText;
    // change form field
    var oDG = document.getElementById(this.sDGId);
    var sDG = 0;
    switch (psClass) {
        case 'private': sDG = 0; break;
        case 'everyone': sDG = 1; break;
        case 'contacts': sDG = 2; break;
    }
    if (oDG) oDG.value = sDG;
    // display additional options
    this.hideOptions();
    this.showOptions(psClass);
}
YAHOO.bm2.recommendations.prototype.showOptions = function(psClass) {
    var sThisOptionId = 'option'+psClass;
    var oThisOption = document.getElementById(sThisOptionId);
    if (oThisOption) oThisOption.style.display = 'block';
}
YAHOO.bm2.recommendations.prototype.hideOptions = function() {
    var oAclOptions = document.getElementById('acloptions');
    oAclOptions.style.display = 'block';
    var oOptions = YAHOO.util.Dom.getElementsByClassName('options', 'div', oAclOptions);
    if (!oOptions) return;
    for (var i=0; i<oOptions.length; i++) {
        if (oOptions[i] && oOptions[i].style) {
            oOptions[i].style.display = 'none';
        }
    }
}
    


/* update toolbar from browser action */
var ytb;
var bm= null;
var theBho = null;
var bInitBho = false;
YAHOO.bm2.updateToolbar = function() {
   ytb = document.createElement( 'OBJECT' );
   ytb.width = 1;
   ytb.height = 1;
   ytb.classid = 'CLSID:EF99BD32-C1FB-11D2-892F-0090271D4F88';
   ytb.id = 'ytb';
   divObjects.appendChild( ytb );

   if (YAHOO.bm2.isVerGTE("6_4_0")) {
     bm = ytb.Bookmark;
   }
   
   YAHOO.bm2.tbReload();
}
YAHOO.bm2.initBho = function() {
    var divo = document.all("divObjects");

    if( null != divo ) {
      if( !bInitBho ) {
        bInitBho = true;

        var bho = document.createElement( "OBJECT" );
        bho.width = 1;
        bho.height = 1;
        bho.classid = "CLSID:02478D28-C3F9-4efb-9B51-7695ECA05670";
        bho.id = "bho";
        divo.appendChild( bho );

        var bho2 = document.createElement( "OBJECT" );
        bho2.width = 1;
        bho2.height = 1;
        bho2.classid = "CLSID:02478D38-C3F9-4efb-9B51-7695ECA05670";
        bho2.id = "bho2";
        divo.appendChild( bho2 );

        if( null != bho2 && "undefined" != typeof(bho2) && null != bho2.object ) {
            theBho = bho2;
        } else if( null != bho && "undefined" != typeof(bho) && null != bho.object ) {
            theBho = bho;
        }
      }
    }

    return theBho;
}
YAHOO.bm2.isVerGTE = function(tv) {
    YAHOO.bm2.initBho();
    if (( null != ytb ) && !ytb.toString() ) {
        var v = theBho.c('gv');

        if( v != "undefined" ) {
            var va = v.split( "." );
            for( i=2; i>=va.length; i-- )
            va[i] = 0;

            var tva = tv.split( "_" );
            for( i=2; i>=tva.length; i-- )
            tva[i] = 0;

            if( (va[0] > tva[0])
              || (va[0] == tva[0] && va[1] > tva[1])
              || (va[0] == tva[0] && va[1] == tva[1] && va[2] >= tva[2]) )
            {
            return true;
            }
        }
    }
    return false;
}

YAHOO.bm2.tbReload = function() {
    if ( null != bm )
        bm.Reload();
}




/* toolbar objects */
// create new folder code
YAHOO.bm2.createNewFolder = function() {
    // form vars
    this.sPFID = 'pfid';
    this.sSelectId = 'fid';
    this.sInputId = 'fname';
    this.sActuatorId = 'addnewact';
    // options vars
    this.sOptionsId = 'addnewfldr';
    this.sOptInputId = 'newname';
    this.sOptSelectId = 'pfidopt';
    this.sOptSubmitId = 'submitmod';
    this.sOptCancelId = 'cancelmod';
    // create folder
    this.newFolder();
}
YAHOO.bm2.createNewFolder.prototype.newFolder = function() {
    // declare module object
    this.oModule = new YAHOO.widget.Module(this.sOptionsId);
    // add event listener
    this.oLink = document.getElementById(this.sActuatorId);
    YAHOO.util.Event.addListener(this.oLink, "click", this.toggleOptions, this);
}
YAHOO.bm2.createNewFolder.prototype.toggleOptions = function(e, obj) {
    // prevent default from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // show module
    obj.oActuator = this;
    obj.show();
}
YAHOO.bm2.createNewFolder.prototype.show = function() {
    // hide actuator
    this.oActuator.style.display = "none";
    // hide select
    this.oSelect = document.getElementById(this.sSelectId);
    this.oSelect.style.display = 'none';
    // render item
    this.oModule.cfg.setProperty("display", "block");
    this.oModule.cfg.setProperty("visible", true);
    // put cursor in right place
    if (!this.oInput) this.oInput = document.getElementById(this.sOptInputId);
    try {
        if (this.oInput && this.oInput.focus) {
            this.oInput.focus();
        };
    } catch (err) {};
    // add event handlers
    this.addFormHandlers();
}
YAHOO.bm2.createNewFolder.prototype.addFormHandlers = function() {
    if (!this.oSubmit) {
        this.oSubmit = document.getElementById(this.sOptSubmitId);
        YAHOO.util.Event.addListener(this.oSubmit, "click", this.submit, this);
    }
    if (!this.oCancel) {
        this.oCancel = document.getElementById(this.sOptCancelId);
        YAHOO.util.Event.addListener(this.oCancel, "click", this.cancel, this);
    }
}
YAHOO.bm2.createNewFolder.prototype.hide = function() {
    // show actuator
    this.oActuator.style.display = "block";
    // show select
    this.oSelect = document.getElementById(this.sSelectId);
    this.oSelect.style.display = 'block';
    // hide module
    this.oModule.cfg.setProperty("display", "none");
    this.oModule.cfg.setProperty("visible", false);
}
YAHOO.bm2.createNewFolder.prototype.cancel = function(e, obj) {
    // prevent default from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // hide module
    obj.hide();
}
YAHOO.bm2.createNewFolder.prototype.submit = function(e, obj) {
    // prevent default from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get values
    var sNewFolder = obj.getInputValue();
    if (!sNewFolder)
        return;
    obj.populateInput(sNewFolder);
    obj.populateSelect(sNewFolder);
    // hide module
    obj.hide();
}
YAHOO.bm2.createNewFolder.prototype.populateSelect = function(psNewFolder) {
    this.clearSelect();
    // get parent folder obj
    this.oOptSelect = document.getElementById(this.sOptSelectId);
    if (!this.oOptSelect) return;
    // get options and value
    this.aOptSelect = this.oOptSelect.getElementsByTagName('option');
    var sParentFolderId = 0;
    for (var i=0; i<this.aOptSelect.length; i++) {
        if (this.aOptSelect[i].selected == true) {
            sParentFolderId = this.aOptSelect[i].value;
        }
    }
    // insert into hidden field
    this.oPFID = document.getElementById(this.sPFID);
    this.oPFID.value = sParentFolderId;
    // insert into other select
    this.oSelect = document.getElementById(this.sSelectId);
    if (!this.oSelect) return;
    // create new node
    var oNewNode = document.createElement('option');
    oNewNode.value = '-1';             // make value --1 for newly added items
    oNewNode.innerHTML = psNewFolder;
    // insert new node in correct location
    this.aSelect = this.oSelect.getElementsByTagName('option');
    if (sParentFolderId!='0' && sParentFolderId!=0) {
        // find index of pfid
        var iPos = 0;
        var iIndex = 0;
        for (i=0; i<this.aSelect.length; i++) {
           if (this.aSelect[i].value==sParentFolderId)  {
               iPos = i;
               iIndex = parseInt(i) + parseInt(1); 
               break;
           }
        }
        // count any potential indents
        var sIndent = '&nbsp;';
        var iOffset = this.aSelect[i].innerHTML.lastIndexOf(sIndent);
        var iCountIndents =  (iOffset!=-1) ? Math.round((iOffset-1)/sIndent.length)+1 : 0;
        var iCountIndents = iCountIndents +2;
        if (iCountIndents > 1) {
            var sIndentString = '';
            for (var ii=0; ii<iCountIndents; ii++) {
                sIndentString += sIndent; 
            }
            oNewNode.innerHTML = sIndentString + oNewNode.innerHTML;
        }
        // insert at position
        this.oSelect.insertBefore(oNewNode, this.aSelect[iIndex]);
    } else {
        // insert right before "uncategorized"
        this.oSelect.appendChild(oNewNode);
    }
    oNewNode.selected = true;
}
YAHOO.bm2.createNewFolder.prototype.clearSelect = function(psNewFolder) {
    // get parent folder obj
    this.oSelect = document.getElementById(this.sSelectId);
    if (!this.oSelect) return;
    // loop through options, remove any with -1 as value
    this.aSelect = this.oSelect.getElementsByTagName('option');
    for (var i=0; i<this.aSelect.length; i++) {
        if (this.aSelect[i] && this.aSelect[i].value=='-1')
            this.oSelect.removeChild(this.aSelect[i]);
    }
}
YAHOO.bm2.createNewFolder.prototype.populateInput = function(newValue) {
    // get new input
    if (newValue) {
        // put in hidden form
        this.oInput = document.getElementById(this.sInputId);
        if (this.oInput)  {
            this.oInput.value = newValue;
        };
    };
}
YAHOO.bm2.createNewFolder.prototype.getInputValue = function() {
    // get new input
    this.oOptInput = document.getElementById(this.sOptInputId);
    if (this.oOptInput) {
        // get value
        var sNewFolder = this.oOptInput.value;
        return sNewFolder.trim();
    };
    return false;
}




/* toolbar functions */
var ex= (window.external) ? window.external : false;
var w = (ex) ? ex.worker : false;

function newFolder() {
    var nf= document.getElementById('nf');
    var nfe= document.getElementById('nfe');
    if (nf && nfe) {
        nfe.disabled= !nf.checked;
    }
}

function resetSelect(poEl) {
    var oSel=poEl;
    for (i=0;i<oSel.options.length;i++) {
        if (oSel.options[i].defaultSelected)
            oSel.options[i].selected=1;
        else
            oSel.options[0].selected=1;
    }
}

function url_escape(sVal) {
    if (!sVal) return '';
    sVal=encodeURIComponent(sVal);
    return sVal;
}

function load() {
    var oDescription = document.getElementById('desc');
    if (oDescription && oDescription.focus) {
        oDescription.focus();
    }
    tbResize();
}


// return field values
function tbAssembleTags(psFieldParent) {
    var oTagsParent = document.getElementById(psFieldParent);
    var oTagAct = document.getElementById('addTags');
    var aTags = YAHOO.util.Dom.getElementsByClassName('suggestedtag', 'input', oTagsParent);
    var sTags = '';
    if (oTagAct && oTagAct.checked==true) {
        for (i in aTags) {
            if (aTags[i].value) {
                sTags += url_escape(aTags[i].value) + ',';
            }
        }
    }
    return sTags;
}
function tbGetFieldValue(psField) {
    var oField = document.getElementById(psField);
    if (oField)
      return url_escape(oField.value)
    else
      return '';
}
function tbGetFID(psFIDID) {
    var oField, oOptions;
    // get field
    oField = document.getElementById(psFIDID);
    // get options
    if (oField) {
        oOptions = oField.getElementsByTagName('option');
    }
    for (i in oOptions) {
        if (oOptions[i].selected) {
            return oOptions[i].value;
        }
    }
    return 0;
}
function tbGetCategoryValue(psField) {
    var oField, aPieces, sName;
    oField = document.getElementById(psField);
    if (oField && oField.checked) {
      aPieces = oField.name.split('[');
      if (aPieces[1]) {
        sName  = aPieces[1].slice(0, -1);
        return sName;
      }
    }
    return '';
}

function tbSave() {
    // if not IE toolbar, use form submit
    if (!ex || !w) return true;

    displayLoading(true);
    var tb_api_url= "";  // if blank, toolbar will use the API URL it has
    // get field values
    var url = tbGetFieldValue('url');
    var title = tbGetFieldValue('ttl');
    var desc = tbGetFieldValue('desc');
    var visibility = (tbGetFieldValue('useacl')) ? tbGetFieldValue('visible') : 0;
    var crumbs = tbGetFieldValue('crumbs');
    var tags = tbAssembleTags('tagfields');
    var fid = tbGetFID('fid');

    var tb_cmd=
        "cmd=save&appid=toolbar&ei=UTF-8&v=1&pcontexttype=T"+
        "&url="+url+
        "&title="+title+
        "&desc="+desc+
        "&visibility="+visibility+
        "&tags="+tags+
        "&crumbs="+crumbs;

    var category0 = (visibility==2) ? tbGetCategoryValue('cat0') : '';
    var category1 = (visibility==2) ? tbGetCategoryValue('cat1'): '';  
    if (category0) {
        tb_cmd += "&categories[]="+category0;
    }
    if (category1) {
        tb_cmd += "&categories[]="+category1;
    }

    // if new folder
    var nf = document.getElementById('fname');
    if (nf && nf.value && fid && fid == '-1' ) {
        var oPFID = document.getElementById('pfid');
        var pfid = oPFID.value;
        var folder=url_escape(nf.value);
        tb_cmd += "&fid=&pfid="+pfid+"&fname="+folder;
    } else {
        tb_cmd += "&pfid=&fname=&fid="+fid;
    }
    // cache
    var oCache = document.getElementById('cache');
    var includeCopy = oCache.checked;
    if (includeCopy) {
        var sep= "function:";
        tb_cmd += "&archive=1&doc=" + sep + "$GETPCONTENT" + sep + "%&docenc=" + sep + "$GETCSET" + sep + "%&doc_type=" + sep + "$GETPMTYPE";
    }

    if (ex && w) {
        var err= w.addbm(tb_api_url, tb_cmd);
    }
    
    return false;
}

function saveResult(err) {
    if (err != 0) {
        changeLoading(bm2_translations.messages.MSG_TB_ERROR);
    } else {
        changeLoading(bm2_translations.messages.MSG_TB_SAVED);
        YAHOO.bm2.updateToolbar();
        ex.end(1);
    }
}


if (window.focus) window.focus();

function onCancelBttnClick(e) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // get which version to use
    var oTarget = YAHOO.util.Event.getTarget(e);
    if (oTarget.className=='toolbar') 
        tbCancel();
    else 
        bmCancel();
}
function tbCancel() {
    ex.end(2);
}
function bmCancel() {
    window.self.close();
}

function tbResize() {
    var oForm = document.getElementById('bmtdoc');
    var sSize = parseInt(oForm.offsetHeight) + 20;
    try { 
        ex.set('height', sSize);
    } catch (e) {
        return;
    }
}

function changeLoading(psText) {
    var oLoadingText = document.getElementById('loadingContent');
    if (oLoadingText) {
        oLoadingText.innerHTML = psText;
    }
    // if 'try again'
    var oTryAgain = document.getElementById('tryagain');
    if (oTryAgain) {
        YAHOO.util.Event.addListener(oTryAgain, "click", removeLoading);
    }
}

function removeLoading(e, obj) {
    // prevent link from firing
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // remove loading notice
    displayLoading(false);
}

function displayLoading(pbOnOff) {
    var oLoading = document.getElementById('loading');
    var oLoadingCntnt = document.getElementById('loadingcnt');
    var oFID = document.getElementById('fid');
    var oForm = document.getElementById('bmtdoc');
    
    
    if (pbOnOff) {
        oLoading.style.display = "block";
        oLoadingCntnt.style.display = "block";
        oLoadingCntnt.style.left = (parseInt(oForm.offsetWidth)-parseInt(oLoadingCntnt.offsetWidth))/2;
        oLoadingCntnt.style.top = (parseInt(oForm.offsetHeight)-parseInt(oLoadingCntnt.offsetHeight))/2;
        oLoading.style.height = YAHOO.util.Dom.getViewportHeight();
        oFID.style.visibility = "hidden";
    } else {
        oLoading.style.display = "none";
        oLoadingCntnt.style.display = "none";
        oFID.style.visibility = "visible";
    }
    return false;
}


/* CSS overrides */
document.write('<style>');
document.write('.nojs {display:block}');
document.write('</style>');
/* TAG FINDER */
YAHOO.bm2.tagFinder = function() {
    // vars
    this.bCanSend = false;        // flag - only allow people to submit if form has content
    this.bUseAC = false;          // flag - set to TRUE when we've loaded AC tags
    this.bACIsInit = false;       // flag - set to TRUE when you initialize AC event listeners
    this.sFormID = 'tagfinder';   // ID of the element to hold the tagFinder
    this.sListID = 'toptagslist'; // ID of the default top-20 tag list
    // create form and initialize
    this.initForm();
}
YAHOO.bm2.tagFinder.prototype.initForm = function() {
    /* this creates the 'Tag Finder' form and adds it to the site */
    // create input
    this.oInput = document.createElement('input');
    this.oInput.type = 'text';
    this.oInput.value = bm2_translations.messages.MSG_TAG_INPUT;
    this.oInput.id = this.sFormID+'input';
    // create submit bttn
    this.oBttn = document.createElement('input');
    this.oBttn.type = 'submit';
    this.oBttn.value = bm2_translations.messages.MSG_TAG_FIND;
    this.oBttn.id = this.sFormID+'bttn';
    // create form
    this.oForm = document.createElement('form');
    this.oForm.id = this.sFormID+'form';
    this.oForm.appendChild(this.oInput);
    this.oForm.appendChild(this.oBttn);
    // add event listeners
    YAHOO.util.Event.addListener(this.oInput, "focus", this.doOnFocus, this);
    // attach to document
    var oParent = document.getElementById(this.sFormID);
    if (oParent) {
        oParent.appendChild(this.oForm);
    }
}

// EVENT HANDLERS
YAHOO.bm2.tagFinder.prototype.doOnFocus = function(e, obj) {
    /* clear the default text in the input field */
    obj.clearInput(e, this);
    // remove all current listeners
    YAHOO.util.Event.purgeElement(this);
    // add event listeners
    YAHOO.util.Event.addListener(obj.oInput, "keypress", obj.doOnKeyPress, obj);
    YAHOO.util.Event.addListener(obj.oBttn, "click", obj.doOnClick, obj);
    if (obj.bUseAC) {
        obj.bACIsInit = true;
        YAHOO.util.Event.addListener(obj.oInput, "keyup", obj.doOnKeyUp, obj);
    }
}
YAHOO.bm2.tagFinder.prototype.doOnKeyPress = function (e, obj) {
    /* this cancels any enter key press */
    // cancel enter key action
    if (e.keyCode==13) {
        // cancel out enter
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false;
        // force submit of form
        if (obj.bCanSend && obj.oInput.value!='' && obj.oInput.value!=bm2_translations.messages.MSG_TAG_INPUT) {
            document.location = '/tags/'+ encodeURIComponent(obj.oInput.value);
        }
    }
}
YAHOO.bm2.tagFinder.prototype.doOnKeyUp = function(e, obj) {
    // handle AC
    if (obj.bUseAC) {
        obj.refineListAC(this.value.toLowerCase());
    }
}
YAHOO.bm2.tagFinder.prototype.doOnClick = function(e, obj) {
    /* this submits form */
    // cancel out default link
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    // tracking
    YAHOO.bm2.beacon('tags', 'find');
    // send user to corrent location
    if (obj.bCanSend && obj.oInput.value!='' && obj.oInput.value!=bm2_translations.messages.MSG_TAG_INPUT) {
        document.location = '/tags/'+ encodeURIComponent(obj.oInput.value);
    }
}

// OTHER ACTIONS
YAHOO.bm2.tagFinder.prototype.clearInput = function(e, poEnterKey) {
    // set canSend flag
    this.bCanSend = true;
    // allow typing
    poEnterKey.className = 'on';
    poEnterKey.color = '#333';
    poEnterKey.value = '';
}

/* TAG FINDER AutoComplete */
YAHOO.bm2.tagFinder.prototype.initAC = function(paACTags) {
    // make sure we have data to work with
    if (!paACTags || !paACTags || !paACTags>0) return;
    this.aACTags = paACTags;
    // allow use of AC
    this.bUseAC = true;
    // create arrays to hold original values & cached matches
    this.aTagsCache = [];
    this.aTagsOriginal = [];
    // get list object
    this.oList = document.getElementById(this.sListID);
    // add event listener
    this.bGotOriginalTagsYet = false;
    if (!this.bACIsInit) {
        YAHOO.util.Event.addListener(this.oInput, "keyup", this.doOnKeyUp, this);
    }
}
YAHOO.bm2.tagFinder.prototype.getDefaultTags = function() {
    this.bGotOriginalTagsYet = true;
    // get original array
    var tmpArray = this.oList.childNodes;
    // copy into my array
    this.aTagsOriginal = []
    for (var i=0; i<tmpArray.length; i++) {
        this.aTagsOriginal.push(tmpArray[i].cloneNode(true));        
    }
}
YAHOO.bm2.tagFinder.prototype.refineListAC = function(psPrefix) {
    // save off original content, if you haven't done it yet
    if (!this.bGotOriginalTagsYet) {
        this.getDefaultTags();
    }
    // clear existing content
    this.oList.innerHTML = '';
    // add AC content
    if (!psPrefix || psPrefix.length<=0) {
        // no prefixes, use default
        for (var i=0; i< this.aTagsOriginal.length; i++) {
            this.oList.appendChild(this.aTagsOriginal[i]);
        }
    } else {
        // use AC list
        var oList = this.getACList(psPrefix);
        for (var i=0; i< oList.length; i++) {
            this.oList.appendChild(oList[i]);
        }
    }
}
YAHOO.bm2.tagFinder.prototype.getACList = function(psPrefix) {
    // return cached array if we have one
    if (this.aTagsCache[psPrefix]) {
        return this.aTagsCache[psPrefix];
    }
    // return matching array 
    this.aTagsCache[psPrefix] = [];
    var i=0;
    var oListItem;
    var bStartedResults = false;  // use this for performance, stop looping once you
                                  // stop getting results that match
    do {
        if (psPrefix==this.aACTags[i].substr(0, psPrefix.length).toLowerCase()) {
           oListItem = this.createACListItem(psPrefix, this.aACTags[i],true);
           this.aTagsCache[psPrefix].push(oListItem);
           bStartedResults = true;
        } else {
           if (bStartedResults) i==this.aACTags.length;
        }
        i++;
    } while (i != this.aACTags.length);
    // if no results
    if (this.aTagsCache[psPrefix].length==0) {
         oListItem = this.createACListItem('', bm2_translations.messages.MSG_TAG_NORESULTS, false);
         this.aTagsCache[psPrefix].push(oListItem);
    }
    // return
    return this.aTagsCache[psPrefix];
}
YAHOO.bm2.tagFinder.prototype.createACListItem = function(psPrefix, psTag, pbLinkOrNot) {
    var oListItem = document.createElement('li');
    // create link item
    if (pbLinkOrNot) {
        var oLink = document.createElement('a');
        oLink.className = 'isTargetable';
        oLink.href = '/tags/'+ psTag;
        oLink.id = 'bb-tag-'+ psTag;
        oLink.innerHTML = '<strong>'+psPrefix+'</strong>'+psTag.substr(psPrefix.length);
        oListItem.appendChild(oLink);
    } else {
        oListItem.innerHTML = psTag;
    }
    // return
    return oListItem;
}/* CSS OVERRIDES FOR JS-ENABLED BROWSERS */
document.write('<style>');
document.write('.nojs {display:none}');
document.write('#addBookmark div.meta {margin-top:0}');
document.write('#actionbttns {display:none !important}');
document.write('/*#folderoptionsact {display:block !important;}');
document.write('#folderoptions {display:none; position:absolute; top:0; right:0; border:1px solid #666; border-top:none; border-left:none; background:#fff; padding:0; margin:0}');
document.write('#folderoptions h4 {display:none}');
document.write('#folderoptions ul {padding:0 !important;  min-width:8em; _width:8em; border:1px solid #aaa}');
document.write('#folderoptions li {border-top:1px dotted #aaa !important;}');
document.write('#folderoptions a {display:block;  padding:.3em 1.5em .3em 25px !important; text-decoration:none}');
document.write('#folderoptions li.first {border-top:none !important}');
document.write('#folderoptions li.usetags a {background:url(\'http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_options_usetags.gif\') 5px 5px no-repeat}');
document.write('#folderoptions li.usefolders a {background:url(\'http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_options_usefolders.gif\') 5px 2px no-repeat}');
document.write('#folderoptions li.addfolder a {background:url(\'http://us.i1.yimg.com/us.yimg.com/i/us/sch/gr2/bm2_options_addfolder.gif\') 5px 2px no-repeat}');
document.write('#folderoptions li a:hover {background-color:#f3f3f3 !important}*/');
document.write('</style>');

