function KMUPlatformSearchHitNavigationSupportUI()
{
  // Create instance of this class inside page with query hit navigation and
  // assign it to a variable UPlatformSearchHitNavigationSupport
  var _hooked = false;
  
  this.Update = _Update;  
  this.GetDimensions = _GetDimensions;
  
  function _Update(status)
  {   
    if (status) {
      _Hook();
      
      if (status.Visible) {       
        _UpdateActionStatus("previous", status.Previous);
        _UpdateActionStatus("best", status.Best);
        _UpdateActionStatus("next", status.Next);
      } 
    }  
  }
  
  function _Hook()
  {
    if (!_hooked) {     
      var list = Element.select(document, ".hit.enabled");                           
      list.each(function(item) {       
        _HookNavigationItem(item);
      }); 
      
      _hooked = true;
    }
  }
  
  function _HookNavigationItem(item)
  {  
    if (item) {
      if (item.hasClassName("previous")) {
        item.observe("click", _DoPreviousSelected);
      } else if (item.hasClassName("best")) {
        item.observe("click", _DoBestSelected);      
      } else if (item.hasClassName("next")) {
        item.observe("click", _DoNextSelected);
      }
    }  
  }
  
  function _UpdateActionStatus(action, status)
  {
    if ((typeof action == "string") && (action != "") && 
        (typeof status == "boolean")) {
      var list = Element.select(document, ".hit.enabled." + action);        
      list.each(function(item) { 
        if (status) {
          Element.show(item);
        } else {
          Element.hide(item);
        }
      }); 

      list = Element.select(document, ".hit.disabled." + action);        
      list.each(function(item) { 
        if (!status) {
          Element.show(item);
        } else {
          Element.hide(item);
        }
      });    
    }
  }

  function _ExecuteAction(action)
  {    
    if (typeof action == "string") {     
      Proxy.Delta.Execute(new Hash({"upaction": "queryhitnavigation", "action": action}));                
    }
  }   
  
  function _DoPreviousSelected(event)
  {  
    _ExecuteAction("previous");    
  }
  
  function _DoBestSelected(event)
  {  
    _ExecuteAction("best");
  }

  function _DoNextSelected(event)
  {  
    _ExecuteAction("next");
  }  
  
  function _GetDimensions()
  {   
    var calcwidth = 75;
    var calcheight = 75;
    try {         
      var containerlist = Element.select(document, ".hit.container");
      if (containerlist.length > 0) {   
        return Element.getDimensions(containerlist[0]);                            
      }           
    } catch(ex) {      
    }
    return {width: calcwidth, height: calcheight}      
  }  
}

function KMUPlatformSearchHitNavigationUI(host, layout)
{  
  // Put instance of this object anywhere so it is always available.
  // Relies on instance of KMUPlatformSearchHitNavigationSupportUI assigned
  // to variable UPlatformSearchHitNavigationSupport inside
  // page with query hit navigation. Assign instance of this object to variable
  // UPlatformSearchHitNavigation (needed to call it self by setTimeout)
  var _host = host;
  if (_host == null) {
    _host = self;
  }  
  var _status = null;
  var _frame = null;
  var _frameHooked = false;    
  var _firstUpdate = true;   
  var _frameBorder = 0;
  var _scrolling = "no";  
  var _layout = layout;
  if (typeof _layout != "string") {
    // vertical-left-center / vertical-right-center 
    // horizontal-top-center / horizontal-bottom-center
    _layout = "vertical-left-center"; 
  }
  
  this.Frame = _frame;
  this.Status = _status;     
  this.Reposition = _Reposition;
  this.SetLayout = _SetLayout;
  this.GetLayout = _GetLayout;  
  this.SetFrameBorder = _SetFrameBorder;
  this.GetFrameBorder = _GetFrameBorder;
  this.SetScrolling = _SetScrolling;
  this.GetScrolling = _GetScrolling;
    
  _Initialize();
  
  function _Initialize()
  {
    _host.Proxy.GetEventSink().observe("magma:querynavigationupdate", _OnQueryNavigationUpdate);
    _host.Proxy.GetEventSink().observe("magma:newdocument", _OnNewDocument);    
  }
  
  function _GetLayout()
  {
    return _layout;
  }
  
  function _SetLayout(value)
  {
    if (typeof value == "string") {
      _layout = value;
    }
  }
  
  function _GetFrameBorder()
  {
    return _frameBorder;
  }
  
  function _SetFrameBorder(value)
  {
    _frameBorder = value;    
  }    
  
  function _GetScrolling()
  {
    return _scrolling;
  }
  
  function _SetScrolling(value)
  {
    _scrolling = value;    
  }   
  
  function _CalculateFramePosition()
  {    
    var contentframe = Proxy.GetContext().UPlatform.GetContentFrame();
    if (contentframe) {  
      var contentbody = _GetBody(contentframe);    
      if (contentbody) {               
        var contentdimensions = {height: contentbody.clientHeight, width: contentbody.clientWidth};       
        var framedimensions = _DetermineFrameDimensions();               
        var calctop = 0;
        var calcleft = 0;
        
        if (_layout == "horizontal-top-center") {
          calcleft = contentbody.scrollLeft + (contentdimensions.width / 2) - (framedimensions.width / 2);                    
          calctop = contentbody.scrollTop;
        } else if (_layout == "horizontal-bottom-center") {
          calcleft = contentbody.scrollLeft + (contentdimensions.width / 2) - (framedimensions.width / 2);                    
          calctop = contentbody.scrollTop + contentdimensions.height - framedimensions.height;          
        } else if (_layout == "vertical-right-center") {
          calctop = contentbody.scrollTop + (contentdimensions.height / 2) - (framedimensions.height / 2);
          calcleft = contentbody.scrollLeft + contentdimensions.width - framedimensions.width;
        } else if (_layout == "center") {
          calctop = contentbody.scrollTop + (contentdimensions.height / 2) - (framedimensions.height / 2);
          calcleft = contentbody.scrollLeft + (contentdimensions.width / 2) - (framedimensions.width / 2);
        } else { // vertical-left-center
          calctop = contentbody.scrollTop + (contentdimensions.height / 2) - (framedimensions.height / 2);
          calcleft = contentbody.scrollLeft;
        }
        
        if (calctop < 0) { calctop = 0; }       
        if (calcleft < 0) { calcleft = 0; }        
        return {Top: calctop, Left: calcleft}              
      }
    }       
    
    return {Top:0,Left:0}
  }
  
  function _DetermineFrameDimensions()
  {   
    if ((_frame) && (_frame.contentWindow) &&
        (_frame.contentWindow.UPlatformSearchHitNavigationSupport)) {
      return _frame.contentWindow.UPlatformSearchHitNavigationSupport.GetDimensions();    
    } else {
      return {width: 75, height: 75}      
    }
  }
    
  function _GetBody(element)
  {
    // Use no prototype in this method
    if (element) {
      var bodylist = null;
      if (element.getElementsByTagName) {
        bodylist = element.getElementsByTagName('body');
      } else if (element.document) {
        bodylist = element.document.getElementsByTagName('body');
      }
      
      if ((bodylist) && (bodylist.length > 0)) {
        return bodylist[0];
      } else {
        return null;
      }
    }
  }
  
  function _CreateFrame()
  {
    if ((_frame == null) && (_status != null) && (_status.Visible) &&
        (_status.Resource != null) && (_status.Resource != "")) {        
      var target = Proxy.GetContext().UPlatform.GetContentFrame();  
      if (target) {      
        var targetbody = _GetBody(target);
        if (targetbody) {
          _frame = target.document.createElement("iframe");                        
          _frame.setAttribute("frameBorder", _GetFrameBorder());
          _frame.setAttribute("allowTransparency", "true");
          _frame.setAttribute("scrolling", _GetScrolling());                  
          targetbody.appendChild(_frame);                                                

          _firstUpdate  = true;                                  
          Event.observe(_frame, "load", _UpdateFrame);  
          Element.extend(_frame);               
          Element.setStyle(_frame, {position:"absolute",top:"0px",
            left:"0px",width:"10px",height:"10px"});          
          Element.hide(_frame);             
          _frame.src = unescape(_status.Resource);           
        }
      }      
    }  
  }  
  
  function _UpdateFrame()
  {      
    if ((_status) && (_status.Visible) && (_frame)) {    
      if ((_frame.contentWindow) && (_frame.contentWindow.UPlatformSearchHitNavigationSupport)) {
        _frame.contentWindow.UPlatformSearchHitNavigationSupport.Update(_status);
      }

      if (_firstUpdate) {
        Event.stopObserving(_frame, "load", _UpdateFrame);                                       
        Element.show(_frame);          
        _Reposition();
        _firstUpdate = false;
      }
    }
  }
    
  function _Reposition()
  {          
    if (_frame) {
      try {
        var position = _CalculateFramePosition();
        var dimensions = _DetermineFrameDimensions();              
        Element.setStyle(_frame, {top: position.Top + "px", left: position.Left + "px",
          width: dimensions.width + "px", height: dimensions.height + "px"});            
      } catch(ex) {        
      }
      
      if (self.UPlatformSearchHitNavigation) {
        window.setTimeout(UPlatformSearchHitNavigation.Reposition.bindAsEventListener(this), 500);
      }      
    }    
  }
    
  function _OnQueryNavigationUpdate(event)
  {    
    _status = event.memo.Parameters.json;
    if ((_status) && (!_status.Visible)) {
      _frame = null;
    } else {    
      if (_frame == null) {            
        _CreateFrame();
      } else {
        _UpdateFrame();
      }    
    }
  }
  
  function _OnNewDocument(event)
  {        
    _frame = null;    
  }
}

function KMUPlatformLinkManagementListUI(list, caption, message, host)
{
  // Supports linkmanager list
  var _captionUI = null;
  var _listUI = null; 
  var _messageUI = null;
  this.ListUI = _listUI;
  this.CaptionUI = _captionUI;
  
  _Initialize(list, caption, message, host);  
  
  function _Initialize(list, caption, message, host)
  {    
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "linkmanager", List: list, 
      UpdateEventId: "magma:linkmanagershow", Host: host});       
    _listUI.SetOnItemSelected(_OnItemSelected);       
    _captionUI = $(caption);    
    _messageUI = $(message);
    
    host.Proxy.GetEventSink().observe("magma:linkmanagerhide", _OnHide);     
    host.Proxy.GetEventSink().observe("magma:linkmanagershow", _OnShow); 
    host.Proxy.GetEventSink().observe("magma:linkmanagermessage", _OnMessage); 
  }
  
  function _OnItemSelected(item)
  {    
    if (item.Id.indexOf("href:") == 0) {            
      Proxy.GetContext().UPlatform.OpenExternal(item.Id.substr(5));      
    } else if (item.Id.indexOf("message") != 0) {          
      Proxy.GetContext().UPlatform.OpenDocument(item.Id, "linkmanager", false);
    } 
  }  
  
  function _OnMessage(event)
  {    
    if (event) {
      _UpdateCaption(event.memo.Parameters.title); 
      _listUI.Clear();      
      if (Object.isElement(_messageUI)) {
        Element.hide(_listUI.GetList());
        Element.show(_messageUI);
        _messageUI.innerHTML = unescape(event.memo.Parameters.text);
      } else {
        Element.show(_listUI.GetList());
        _listUI.List.innerHTML = unescape(event.memo.Parameters.text);
      }
    }
  }
  
  function _OnHide()
  {               
    _listUI.Clear();
    if (Object.isElement(_messageUI)) {
      Element.hide(_messageUI);
    }    
    _UpdateCaption("");
  }  

  function _OnShow(event)
  {
    if (Object.isElement(_messageUI)) {
      Element.hide(_messageUI);
    }
    
    Element.show(_listUI.GetList())
    _UpdateCaption(event.memo.Parameters.title);
  } 
  
  function _UpdateCaption(text)
  {   
    if (_captionUI) {
      if (typeof text != "string") {
        text = "";
      }    
      _captionUI.innerHTML = unescape(text);
    }  
  }
}

function KMUPlatformActiveDocumentListUI(list, host, maxItemCount)
{
  // Supports active document list
  var _listUI = null; 
  this.ListUI = _listUI;
  
  _Initialize(list, host);  
  
  function _Initialize(list, host)
  {      
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "activedocument", List: list, 
      UpdateEventId: "magma:activedocumentlistupdated", Host: host});       
    _listUI.SetOnItemSelected(_OnItemSelected); 
    if (typeof maxItemCount == "number") {
      _listUI.SetMaxItemCount(maxItemCount);
    }
  }
  
  function _OnItemSelected(item)
  {
    Proxy.GetContext().UPlatform.OpenDocument(item.Id, "history", false);   
  }   
}

function KMUPlatformSlotLicenseListUI(list, host, maxItemCount)
{
  // Supports slot license item list
  var _listUI = null; 
  this.ListUI = _listUI;
  
  _Initialize(list, host);  
  
  function _Initialize(list, host)
  {      
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "slotlicenseitems", List: list, 
      UpdateEventId: "magma:slotlicenselistupdated", Host: host});       
    _listUI.SetOnItemSelected(_OnItemSelected); 
    if (typeof maxItemCount == "number") {
      _listUI.SetMaxItemCount(maxItemCount);
    }
  }
  
  function _OnItemSelected(item)
  {
    Proxy.GetContext().UPlatform.OpenDocument(item.Id, "slotlicense", false);   
  }   
}

function KMUPlatformFavoriteListUI(list, host, maxItemCount)
{
  // Supports favorite list
  var _listUI = null;
  this.ListUI = _listUI;
  
  _Initialize(list, host);
  
  function _Initialize(list, host)
  {    
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "favorites", List: list, 
      UpdateEventId: "magma:favoriteslistupdated", Host: host});           
    _listUI.SetOnItemSelected(_OnItemSelected);            
    _listUI.SetOnItemCommand(_OnItemCommand);  
    if (typeof maxItemCount == "number") {
      _listUI.SetMaxItemCount(maxItemCount);
    }
  }
  
  function _OnItemSelected(item)
  {    
    Proxy.GetContext().UPlatform.Favorites.Execute(item.Id);
  }
  
  function _OnItemCommand(command, item)
  {    
    if (command === "delete") {      
      _listUI.DeleteItem(item, function() {          
        Proxy.GetContext().UPlatform.Favorites.Delete(item.Id);
      });
    } 
  }
}

function KMUPlatformSearchServiceSupportUI(options)
{
  var _options = null;   
  var _fieldList = new Array();
  this.Execute = _Execute;
  this.AddField = _AddField;
  this.GetQuery = _GetQuery;
  this.SetQuery = _SetQuery;
  this.QueryOptions = null;  
  
  _Create(options);
  
  function _Create(options)
  {
    if (options != null) {  
      _options = options;           
            
      if (!_options.Host) {
        _options.Host = self;
      }
        
      for (var key in _options) {
        if ((Object.isString(_options[key])) &&
            ((key == "QueryField") || (key == "CommandQuery") || (key == "ResultArea"))) {        
          _options[key] = $(_options[key]);
        }
      }           

      if ((Object.isElement(_options.QueryField)) &&
          (Object.isElement(_options.CommandQuery))) {   
        Event.observe(_options.CommandQuery, "click", _Execute);
        Event.observe(_options.QueryField, "keypress", _OnKeyPress);

        if (Object.isElement(_options.ResultArea)) {
          _options.Host.Proxy.GetEventSink().observe("magma:searchserviceresults", _OnResults);
        }        
      } else {
        _options = null;
      }
    }  
  }
  
  function _AddField(field)
  {
    if (field != null) {
      if (field.Element) {
        field.Element = $(field.Element);
        _HookLookupField(field);
      }
      
      _fieldList.push(field);                    
    }
  }
  
  function _HookLookupField(field)
  {
    if ((field) && (Object.isElement(field.Element))) {
      Event.observe(field.Element, "keypress", _OnKeyPress);
    
      if ((Object.isString(field.Property)) && (!field.Property.blank()) && 
          ((field.Value == null) || (Object.isUndefined(field.Value)))) {        
        if (field.ChoicesElement) {
          field.ChoicesElement = $(field.ChoicesElement);
        }
          
        if (!Object.isElement(field.ChoicesElement)) {
          field.ChoicesElement = $(field.Element.id + "_choices");
        }
        
        if (!Object.isNumber(field.MaxLookupResultCount)) {
          field.MaxLookupResultCount = 10;
        }
        
        if (Object.isElement(field.ChoicesElement)) {          
          new Ajax.Autocompleter(field.Element.id, 
            field.ChoicesElement.id, 
            Proxy.GetValues().Application.Module,
            {paramName: "__value", 
             parameters: "upaction=searchclientlookup&__property=" + field.Property +
             "&__resultsperpage=" + field.MaxLookupResultCount});
        }
      }
    }
  }
  
  function _Execute(startPage, queryOptions)
  {  
    if (_options != null) {     
      var query = _GetQuery();
      if ((query == null) || (!Object.isString(query))) {
        query = "";
      }

      // Assemble query options
      var queryoptions;
      if (Object.isArray(queryOptions)) {
        queryoptions = queryOptions;
      } else {
        queryoptions = new Array();
      }
      _CollectQueryOptions(queryoptions);
      if (Object.isFunction(_options.OnCollectQueryOptions)) {      
        try {          
          _options.OnCollectQueryOptions(queryoptions);
        } catch(e) {
        }        
      }
                  
      Proxy.GetContext().UPlatform.SearchService.Execute(query,
        { "StartPage": startPage, "QueryOptions": queryoptions, 
          "ServiceId": _options.ServiceId, "DefaultScope": _options.DefaultScope });         
    }
  }
  
  function _CollectQueryOptions(queryOptions)
  {
    _fieldList.each(function(field) {
      if ((Object.isString(field.Property)) && (!field.Property.blank())) {
        // Check whether optional element is enabled
        if ((!Object.isElement(field.Element)) || (!field.Element.disabled)) {        
          // Add property option      
          if (Object.isString(field.Value)) {
            _CollectStaticQueryOption(field, queryOptions);
          } else {   
            _CollectDynamicQueryOption(field, queryOptions);
          }
        }
      } 
    });
  }
  
  function _CollectStaticQueryOption(field, queryOptions)
  {
    if ((field) && (Object.isArray(queryOptions)) &&
        (Object.isString(field.Value))) {    
      // Property with default value, optionally determined by boolean element
      if ((!Object.isElement(field.Element)) ||
          ((field.Element.checked) && (field.Element.checked === true))) {
        _AddPropertyQueryValue(field, queryOptions, field.Value);        
      }    
    }
  }
  
  function _CollectDynamicQueryOption(field, queryOptions)
  {
    if ((field) && (Object.isArray(queryOptions)) && (Object.isElement(field.Element))) {
      var value = null;
      if ((Object.isString(field.Type)) && (field.Type == "CurrentBook")) {
        // Special field "CurrentBook", add property with id of current book to query
        if ((Object.isElement(field.Element)) && (field.Element.checked) && (field.Element.checked === true)) {
          var currentbook = Proxy.GetContext().UPlatform.CurrentBook();
          if (currentbook) {
            value = currentbook.UPlatformId;              
          }
        }        
      } else if (field.Element.GetValue) {
        value = field.Element.GetValue(); // Knowmax hint field 
      } else {
        value = Form.Element.getValue(field.Element);   
      }          

      if (Object.isString(value)) {
        _AddPropertyQueryValue(field, queryOptions, value);        
      } else if (Object.isArray(value)) {
        value.each(function(item) {          
          _AddPropertyQueryValue(field, queryOptions, item);          
        });                       
      }  
    }
  }
  
  function _AddPropertyQueryValue(field, queryOptions, value)
  {
    if ((field) && (Object.isArray(queryOptions)) && 
        (Object.isString(value)) && (!value.blank())) {  
      if (((field.AsIs) && (field.AsIs === true)) || 
          (value.startsWith('"')) || (value.endsWith('"')) ||
          (value.startsWith("'")) || (value.endsWith("'")) ||
          (value.indexOf(" ") < 0)) {
        if (Object.isString(field)) {
          queryOptions.push({Property: field, Value: value});
        } else {
          queryOptions.push({Property: field.Property, Value: value});
        }
      } else if (Object.isString(field)) {        
        queryOptions.push({Property: field, Value: '"' + value + '"'});
      } else {
        queryOptions.push({Property: field.Property, Value: '"' + value + '"'});
      }
    }
  }
  
  function _OnKeyPress(event) 
  {    
    if (event.keyCode == Event.KEY_RETURN) {                  
      event.returnValue = false;
  	  if (event.preventDefault) {
  		  event.preventDefault();
  	  }
		  try {			
	  	  event.keyCode = 0;
		  } catch(e) {
		  }   
      
      _Execute();      
    }
  }

  function _OnResults(event)
  {    
    if ((event.memo.HasData) && (event.memo.Id) && (event.memo.Source) &&
        (_options) && (Object.isElement(_options.ResultArea))) {    
      var delta = event.memo.Source.$(event.memo.Id);            
      if (delta) {        
        _HookUnHook(Event.stopObserving);
        _options.ResultArea.innerHTML = delta.innerHTML; 
        _HookUnHook(Event.observe);        
      }
    }         
  }

  function _HookUnHook(eventMethod)
  {
    if ((_options != null) && (Object.isElement(_options.ResultArea)) &&
        (Object.isFunction(eventMethod))) {    
      var itemlist = Element.select(_options.ResultArea, "[documentid]");
      itemlist.each(function(item) {
        _HookUnHookResultItem(item, eventMethod);        
      });         
            
      var pagelist = Element.select(_options.ResultArea, "[pageid]");
      pagelist.each(function(page) {
        _HookUnHookPageItem(page, eventMethod);        
      }); 
      
      var querysuggestionlist = Element.select(_options.ResultArea, "[querysuggestion]");
      querysuggestionlist.each(function(querysuggestion) {
        _HookUnHookQuerySuggestion(querysuggestion, eventMethod);
      });      
    }
  }
  
  function _HookUnHookResultItem(item, eventMethod)
  {  
    if ((Object.isElement(item)) && (Object.isFunction(eventMethod))) {   
      var iteminfo = _GetResultItemInfo(item);
      if (iteminfo) {
        // Hook execute action
        var actionlist = Element.select(item.Element, "[action='execute']");
        actionlist.each(function(action) {
          eventMethod(action, "mouseover", _DoMouseOver);
          eventMethod(action, "mouseout", _DoMouseOut); 
          eventMethod(action, "click", _DoResultExecute);
        });      
        
        // Hook duplicates action
        actionlist = Element.select(item.Element, "[action='duplicates']");
        actionlist.each(function(action) {
          eventMethod(action, "mouseover", _DoMouseOver);
          eventMethod(action, "mouseout", _DoMouseOut); 
          eventMethod(action, "click", _DoDuplicateExecute);
        });                      
      }           
    }
  }  

  function _DoResultExecute(event)
  {
    var iteminfo = _GetResultItemInfo(event.element());
    if (iteminfo != null) {      
      if ((iteminfo.Id.indexOf("http://") != -1) ||
          (iteminfo.Id.indexOf("https://") != -1) ||
          (iteminfo.Id.indexOf("ftp://") != -1)) {        
        Proxy.GetContext().UPlatform.OpenExternal(iteminfo.Id);
      } else if (iteminfo.Id.indexOf(":") != -1) {
        // non Quest
        Proxy.GetContext().UPlatform.OpenDocumentEx(iteminfo.Id,
          new Hash({"colorquery": Proxy.GetContext().UPlatform.SearchService.GetQuery()}));        
      } else {      
        // Quest      
        Proxy.GetContext().UPlatform.OpenDocumentEx("kmuplatformquestquery:" + iteminfo.Id,
          new Hash({"colorquery": Proxy.GetContext().UPlatform.SearchService.GetQuery()}));
      }
    }
  }
  
  function _DoDuplicateExecute(event)
  {
    var iteminfo = _GetResultItemInfo(event.element());
    if (iteminfo != null) {            
      queryoptions = new Array();
      _AddPropertyQueryValue("duplicates", queryoptions, iteminfo.InternalId);      
      _Execute(null, queryoptions);
    }
  }
  
  function _DoSuggestionExecute(event)
  {
    if ((event) && (event.element())) {
      var query = event.element().getAttribute("querysuggestion"); 
      if ((query) && (!query.empty()) && (_SetQuery(query))) {        
        _Execute();                    
      }
    }
  }
  
  function _SetQuery(value)
  {
    if (!_options.QueryField.disabled) {           
      if (_options.QueryField.SetValue) {
        _options.QueryField.SetValue(value);
        return true;
      } else {
        _options.QueryField.value = value;
        return true;
      }
    }

    return false;    
  }
  
  function _GetQuery()
  {
    if (!_options.QueryField.disabled) {           
      if (_options.QueryField.GetValue) {
        return _options.QueryField.GetValue();        
      } else {
        return _options.QueryField.value;        
      }
    }

    return null;    
  }

  function _HookUnHookPageItem(page, eventMethod)  
  {
    if ((Object.isElement(page)) && (Object.isFunction(eventMethod))) {   
      var pageinfo = _GetPageItemInfo(page);
      if (pageinfo) {
        var actionlist = Element.select(page.Element, "[action='execute']");
        actionlist.each(function(action) {
          eventMethod(action, "mouseover", _DoMouseOver);
          eventMethod(action, "mouseout", _DoMouseOut); 
          eventMethod(action, "click", _DoPageExecute);
        });            
      }
    }  
  }
     
  function _DoPageExecute(event)
  {
    var pageinfo = _GetPageItemInfo(event.element());
    if (pageinfo != null) {      
      _Execute(pageinfo.Id);
    }    
  } 
  
  function _HookUnHookQuerySuggestion(querysuggestion, eventMethod)  
  {
    if ((Object.isElement(querysuggestion)) && (Object.isFunction(eventMethod))) {   
      eventMethod(querysuggestion, "mouseover", _DoMouseOver);
      eventMethod(querysuggestion, "mouseout", _DoMouseOut); 
      eventMethod(querysuggestion, "click", _DoSuggestionExecute);
    }  
  }
  
  function _GetResultItemInfo(element)
  {      
    var item = _GetResultItemElementFromElement(element);
    if (item != null) {      
      var internalid = item.getAttribute("internalid");
      var documentid = item.getAttribute("documentid");      
      if (typeof documentid == "string") {
        if ((typeof internalid != "string") || (internalid == "")) {
          internalid = documentid;
        }
        return {Id: documentid, InternalId: internalid, Element: item};
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
  
  function _GetResultItemElementFromElement(element)
  {
    while ((element) && (Object.isElement(element))) {      
      if (element.readAttribute("documentid") != null) {
        return element;
      }
      element = element.up();
    }    
    return null;
  }  

  function _GetPageItemInfo(element)
  {      
    var page = _GetPageItemElementFromElement(element);
    if (page != null) {            
      var pageid = page.getAttribute("pageid");
      if (typeof pageid == "string") {
        return {Id: pageid, Element: page};
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
  
  function _GetPageItemElementFromElement(element)
  {
    while ((element) && (Object.isElement(element))) {      
      if (element.readAttribute("pageid") != null) {
        return element;
      }
      element = element.up();
    }    
    return null;
  }

  function _DoMouseOver(event)  
  {
    _UpdateOverClass(event.element(), true);
  }
  
  function _DoMouseOut(event)
  {
    _UpdateOverClass(event.element(), false);
  }
  
  function _UpdateOverClass(element, overNode)
  {    
    if (Object.isElement(element)) {
      if (overNode) {      
        Element.addClassName(element, "over");   
      } else {      
        Element.removeClassName(element, "over");
      }    
    }           
  }  
}

function KMUPlatformSearchSupportUI(options)
{
  // Create instance of this object to support UI for searching using Knowmax Quest.
  // Only QueryField and CommandQuery are mandatory.  
  var _options = null;
  var _OnScopeCommand = null;
  var _scopeDeltaFrame = null;
  this.Execute = _Execute;
  this.SetOnScopeCommand = _SetOnScopeCommand;
  
  _Create(options);
  
  function _Create(options)
  {       
    if (options != null) {  
      _options = options;
      for (var key in _options) {
        if ((typeof _options[key] == "string") && (key != "Resource")) {            
          _options[key] = $(_options[key]);
        }
      }

      if ((Object.isElement(_options.QueryField)) &&
          (Object.isElement(_options.CommandQuery))) {   
        Event.observe(_options.CommandQuery, "click", _Execute);
        Event.observe(_options.QueryField, "keypress", _OnKeyPress);
        Proxy.GetEventSink().observe(UPLATFORM.RELEASE.LIBRARYCHANGED, _OnLibraryChanged);
        
        _HookUnHookScopeList(Event.observe);        
      } else {
        _options = null;
      }
    }
  }
  
  function _GetScopeDeltaFrame()
  {  
    if ((_scopeDeltaFrame == null) || (typeof _scopeDeltaFrame == "undefined")) {    
      var frame = Proxy.Delta.CreateIFrameObject();
      if (frame) {      
        Event.observe(frame, "load", _scopeDeltaFrameLoaded);            
        _scopeDeltaFrame = frame.contentWindow
      }
    }  
    return _scopeDeltaFrame;
  }
  
  function _OnLibraryChanged()
  {        
    if ((_options.Resource) && (typeof _options.Resource.ScopeXslt == "string")) {
      Proxy.Delta.Execute(new Hash({"action": "transform", 
        "xml": "content:kmuplatformrelease/xmlresourcebyresourceid|id=searchscopes", 
        "prexslt": _options.Resource.ScopeXslt}), _GetScopeDeltaFrame(), true); 
    }
  }
  
  function _scopeDeltaFrameLoaded()
  {       
    _HookUnHookScopeList(Event.stopObserving);
    _options.ScopeList.innerHTML = _scopeDeltaFrame.document.body.innerHTML;    
    _HookUnHookScopeList(Event.observe);
  }
  
  function _SetOnScopeCommand(value)
  {
    _OnScopeCommand = value;
  }
   
  function _HookUnHookScopeList(eventMethod)
  {
    if ((_options != null) && (Object.isElement(_options.ScopeList)) &&
        (Object.isFunction(eventMethod))) {    
      // Weird, Element.select does not work in Safari for this case      
      var scopelist = _options.ScopeList.getElementsByTagName("INPUT");      
      for (var i= 0; i < scopelist.length;i++) {
        Element.extend(scopelist[i]);
        _HookUnHookScope(scopelist[i], eventMethod);  
      }      
    }
  }  
  
  function _HookUnHookScope(scope, eventMethod)
  {
    if ((scope) && (Object.isFunction(eventMethod))) {
      var scopeinfo = _GetScopeInfo(scope);
      if (scopeinfo) {
        try {                              
          eventMethod(scope, "mouseover", _DoScopeMouseOver);
          eventMethod(scope, "mouseout", _DoScopeMouseOut); 
        } catch(ex) {          
        }
      }
      
      var commandlist = Element.select(scope, "[itemcommand]");
      commandlist.each(function(command) {
        try {
          eventMethod(command, "click", _DoScopeCommand);
        } catch(ex) {
        }
      });
      
      return scopeinfo;
    }
  }
    
  function _UpdateScopeOverClass(element, overNode)
  {    
    var scopeinfo = _GetScopeInfo(element);
    if (scopeinfo != null) {                 
      if (overNode) {
        Element.addClassName(scopeinfo.Element, "over");   
      } else {
        Element.removeClassName(scopeinfo.Element, "over");
      }
    }         
  }    
  
  function _DoScopeMouseOver(event)
  {
    _UpdateScopeOverClass(event.element(), true);
  }
  
  function _DoScopeMouseOut(event)
  {
    _UpdateScopeOverClass(event.element(), false);  
  }
  
  function _DoScopeCommand(event)
  {
    Event.stop(event);   
    var command = event.element().getAttribute("scopecommand");    
    var scopeinfo = _GetScopeInfo(event.element());  
    if ((_OnScopeCommand) && (scopeinfo) && (command)) {            
      _OnScopeCommand(command, scopeinfo);
    }  
  }
  
  function _GetScopeInfo(element)
  {      
    var scope = _GetScopeElementFromElement(element);
    if (scope != null) {      
      var scopeid = scope.getAttribute("scopeid");
      var scopeprefix = scope.getAttribute("scopeprefix");
      var scopevalue = scope.getAttribute("scopevalue");      
      var scopetype = scope.getAttribute("scopetype");
      if (typeof scopeid == "string") {
        return {Id: scopeid, Prefix: scopeprefix, Value: scopevalue, Type: scopetype, Element: scope};
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
  
  function _GetScopeElementFromElement(element)
  {
    while ((element) && (Object.isElement(element))) {      
      if (element.readAttribute("scopevalue") != null) {
        return element;
      }
      element = element.up();
    }    
    return null;
  }  
    
  function _Execute()
  {  
    if (_options != null) {
      Proxy.GetContext().UPlatform.Quest.JustAnd = 
        ((Object.isElement(_options.JustAndField)) && (_options.JustAndField.checked));                
      Proxy.GetContext().UPlatform.Quest.CurrentBook = 
        ((Object.isElement(_options.ScopeBook)) && (_options.ScopeBook.checked));
      Proxy.GetContext().UPlatform.Quest.CurrentDocument = 
        ((Object.isElement(_options.ScopeDocument)) && (_options.ScopeDocument.checked));
      
      var query = _options.QueryField.value;      
      if (_options.QueryField.GetValue) {
        query = _options.QueryField.GetValue();
      }      
      
      if (Object.isElement(_options.ScopeList)) {                
        var scopeinfo;
        var iscopes = new Array();
        var escopes = new Array();
        // Weird, Element.select does not work in Safari for this case        
        var scopelist = _options.ScopeList.getElementsByTagName("INPUT");      
        for (var i=0;i < scopelist.length;i++) {
          scopeinfo = _GetScopeInfo(scopelist[i]);  
          if ((scopeinfo) && (Object.isString(scopeinfo.Value)) && 
              (scopeinfo.Value != "") && (scopelist[i].checked)) {           
            if (scopeinfo.Type === "iscope") {
              iscopes.push(scopeinfo.Value);
            } else if (scopeinfo.Type === "escope") {
              escopes.push(scopeinfo.Value);
            }                       
          } 
        }                                     
        Proxy.GetContext().UPlatform.Quest.IncludeScopes = iscopes;
        Proxy.GetContext().UPlatform.Quest.ExcludeScopes = escopes;
      } else {
        Proxy.GetContext().UPlatform.Quest.IncludeScopes = null;
        Proxy.GetContext().UPlatform.Quest.ExcludeScopes = null;      
      }      
      
      Proxy.GetContext().UPlatform.Quest.Execute(query);    
    }
  }
  
  function _OnKeyPress(event) 
  {    
    if (event.keyCode == Event.KEY_RETURN) {                  
      event.returnValue = false;
  	  if (event.preventDefault) {
  		  event.preventDefault();
  	  }
		  try {			
	  	  event.keyCode = 0;
		  } catch(e) {
		  }   
      
      _Execute();      
    }
  }
}

function KMUPlatformFavoriteSupportUI(options)
{
  // Create instance of this object to support UI for adding favorites.
  // ExternalField, ApplicationField and CommandBrowse are all optional. (only usefull for standalone versions)  
  var _options = null;
  var _type = null;  
  
  _Create(options);
  
  function _Create(options)
  {
    if (options != null) {
      _options = options;
      for (var key in _options) {
        if (typeof _options[key] == "string") {          
          _options[key] = $(_options[key]);
        }
      }             
  
      if ((Object.isElement(_options.AddressField)) && (Object.isElement(_options.TitleField)) &&
          (Object.isElement(_options.CommandAdd))) {
        Event.observe(_options.CommandAdd, "click", _OnAdd);  
      
        if ((Object.isElement(_options.ApplicationField)) && (Object.isElement(_options.ExternalField)) &&
            (Object.isElement(_options.CommandBrowse)) && (_options.Host)) {
          _options.ApplicationField.disabled = Proxy.GetValues().Application.IsServer;
          Event.observe(_options.ApplicationField, "click", _OnUpdateType);
          Event.observe(_options.ExternalField, "click", _OnUpdateType);    
          Event.observe(_options.CommandBrowse, "click", _OnBrowse);
          _options.Host.Proxy.GetEventSink().observe("magma:favoritesfileselected", _OnFileSelected);         
        }
        
        _SetType("external");
      } else {
        _options = null;
      }
    }
  }
  
  function _OnAdd(event)
  {
    if (_options != null) {
      var address = _options.AddressField.value;
      var title = _options.TitleField.value;
      if ((_options.AddressField.GetValue) && (_options.TitleField.GetValue)) {
        address = _options.AddressField.GetValue();
        title = _options.TitleField.GetValue();
      }
    
      if ((address) && (title) && (address != "") && (title != "")) {        
        Proxy.GetContext().UPlatform.Favorites.Add(address, _type, title);

        if ((_options.AddressField.Clear) && (_options.TitleField.Clear)) {
          _options.AddressField.Clear();
          _options.TitleField.Clear();
        } else {
          _options.AddressField.value = "";
          _options.TitleField.value = "";
        }
      }
    }
  }
  
  function _SetType(type)
  {
    if (_options != null) {
      if ((type === "application") && (Object.isElement(_options.ApplicationField)) && 
          (Object.isElement(_options.CommandBrowse)) && 
          (Proxy.GetValues().Application.IsClient)) {
        _options.ApplicationField.checked = true;
        Element.show(_options.CommandBrowse);      
        _type = "application";
      } else {
        if (Object.isElement(_options.ExternalField)) {
          _options.ExternalField.checked = true;
        }
        if (Object.isElement(_options.CommandBrowse)) {
          Element.hide(_options.CommandBrowse); 
        }
        _type = "external";
      } 

      if (_options.AddressField.Clear) {
        _options.AddressField.Clear();
      } else {
        _options.AddressField.value = "";
      }
    }
  } 
  
  function _OnUpdateType(event)
  {
    if ((_options != null) && (event.element() == _options.ApplicationField)) {
      _SetType("application");
    } else {
      _SetType("external");
    }
  }
  
  function _OnBrowse(event)
  {
    Proxy.Delta.Execute(new Hash({"action": "selectfavfile"}));      
  }
  
  function _OnFileSelected(event)
  {
    if ((_options != null) && (event.memo.HasData) && 
        (event.memo.Source) && (event.memo.Id)) {      
      var datavalue = event.memo.Source.$(event.memo.Id);            
      if (datavalue) {
        if (_options.AddressField.SetValue) {
          _options.AddressField.SetValue(datavalue.innerHTML);
        } else {
          _options.AddressField.value = datavalue.innerHTML;
        }        
      }
    }
  }
}

function KMUPlatformSearchResultListUI(list, navigation, host)
{
  // Supports search result list with navigation buttons.
  // Make sure to add isolateeventdata="True" attribute to kmuplatformquestquery
  // node in config file when using this component.    
  var _listUI = null;
  var _navigation = $(navigation);
  var _host = host;
  if (_host == null) {
    _host = self;
  }
  
  this.ListUI = _listUI;
  
  _Initialize(list);  
  
  function _Initialize(list)
  {
    var EVENTID_RESULTSUPDATED = "magma:queryresultsupdated";
    var EVENTID_EXECUTED = "magma:queryexecuted";
      
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "queryresults", List: list, 
      UpdateEventId: EVENTID_RESULTSUPDATED, Host: _host});           
    _listUI.SetOnItemSelected(_OnItemSelected);        
    
    _host.Proxy.GetEventSink().observe(EVENTID_RESULTSUPDATED, _OnNavigationUpdated);
    _host.Proxy.GetEventSink().observe(EVENTID_EXECUTED, _OnQueryExecuted);
  }
  
  function _OnQueryExecuted(event)
  {
    if ((event.memo.Parameters.totalcount == 0) && (_navigation)) {
      _navigation.innerHTML = "";
      _listUI.Clear();      
    }    
  }
  
  function _OnNavigationUpdated(event)
  {        
    if ((event.memo.HasData) && (event.memo.Source) && (event.memo.Id)) {      
      var deltanavigation = event.memo.Source.$(event.memo.Id + "navigation");            
      if ((deltanavigation) && (_navigation)) {
        _navigation.innerHTML = deltanavigation.innerHTML;        
        _HookNavigation();
      }
    }    
  }
  
  function _HookNavigation()
  {
    if (_navigation) {
      var itemlist = Element.select(_navigation, "[itemtype]");
      itemlist.each(function(item) {
        _HookNavigationItem(item);
      });  
    }
  }
  
  function _HookNavigationItem(item)
  {
    if (item) {
      var iteminfo = _GetNavigationItemInfo(item);       
      if ((iteminfo != null) && (iteminfo.Enabled)) {
        if (!iteminfo.Selected) {
          item.observe("click", _DoNavigationItemSelected);
        }
        item.observe("mouseover", _DoNavigationItemMouseOver);
        item.observe("mouseout", _DoNavigationItemMouseOut);
      }
    }
  }   
  
  function _DoNavigationItemSelected(event)
  {
    var iteminfo = _GetNavigationItemInfo(event.element());    
    if (iteminfo != null) {
      Proxy.Delta.Execute(new Hash({"upaction": "queryresults", 
        "navigate": iteminfo.Type, "value": iteminfo.Page}));            
    }  
  }
  
  function _GetNavigationItemInfo(element)
  {      
    var item = _GetNavigationItemElementFromElement(element);
    if (item != null) {      
      var itemtype = item.getAttribute("itemtype");
      var selected = item.getAttribute("itemselected") == "True";
      var enabled = item.getAttribute("itemenabled") == "True";   
      var page = item.getAttribute("itempage");
      if (typeof itemtype == "string") {
        return {"Type": itemtype, "Selected": selected, 
          "Enabled": enabled, "Page": page, "Element": item};
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
  
  function _GetNavigationItemElementFromElement(element)
  {
    while ((element) && (typeof element == "object")) {      
      if (element.readAttribute("itemtype") != null) {
        return element;
      }
      element = element.up();
    }    
    return null;
  }
  
  function _DoNavigationItemMouseOver(event)  
  {
    _UpdateNavigationItemOverClass(event.element(), true);
  }
  
  function _DoNavigationItemMouseOut(event)
  {
    _UpdateNavigationItemOverClass(event.element(), false);
  }
  
  function _UpdateNavigationItemOverClass(element, overNode)
  {    
    var iteminfo = _GetNavigationItemInfo(element);
    if (iteminfo != null) {                 
      if (overNode) {      
        Element.addClassName(iteminfo.Element, "over");   
      } else {      
        Element.removeClassName(iteminfo.Element, "over");
      }
    }         
  }    
  
  function _OnItemSelected(item)
  {    
    Proxy.GetContext().UPlatform.OpenDocument(item.Id, "queryresults", false);     
  }
}

function KMUPlatformReleaseLibraryComboUI(combo, restartOnChange, errorField)
{
  // Supports simple combobox for selecting library within current release.
  var _combo = $(combo);
  var _errorField = $(errorField);
  var _restartOnChange = restartOnChange
  if (typeof _restartOnChange != "boolean") {
    _restartOnChange = true;
  }

  _Initialize();
  
  function _Initialize()
  {
    if (Object.isElement(_combo)) {
      _combo.observe('change', _OnLibrarySelect);      
      Proxy.GetEventSink().observe(UPLATFORM.RELEASE.LIBRARYCHANGEFAILED, _OnLibraryChangeFailed);      
      Proxy.GetEventSink().observe(UPLATFORM.RELEASE.LIBRARYCHANGED, _OnLibraryChanged);            
    }    
  }
  
  function _OnLibrarySelect(event)
  {
    if ((event) && (event.element())) {      
      var id = event.element().options[event.element().selectedIndex].value;      
      if ((id != null) && (typeof id == "string")) {        
        Proxy.GetContext().UPlatform.Release.SelectLibrary(id);  
      }
    }
  }
    
  function _OnLibraryChangeFailed(event)
  {  
    if ((event) && (event.memo) && (Object.isElement(_errorField))) {
      _errorField.innerHTML = unescape(event.memo);
      Element.show(_errorField);
    } 
  }  
  
  function _OnLibraryChanged(event)
  {
    // Update selected library in list    
    if ((Object.isElement(_combo)) && (event) && (event.memo) && (event.memo.InDirect) &&
        (event.memo.Release) && (event.memo.Release.Library)) {      
      for (var index=0; index<_combo.length; index++) {
        if (_combo.options[index].value == event.memo.Release.Library.Id) {
          _combo.selectedIndex = index;
          break;
        }
      }
    }    
  }
}

function KMUPlatformVaultStorageUI(options)
{
  var _options = options;
  var _dataSaveRequestData = null;
  var _openFileNameRequestData = null;
  var _afterSaveMethod = null;
  var _saveDialogLoadedRegistered = false;
  var _loadDialogLoadedRegistered = false;
  var _managementDialogLoadedRegistered = false;
  
  _Create();

  function _Create()
  {    
    Proxy.GetEventSink().observe(UPLATFORM.VAULTSTORAGE.DATAUPDATED, _OnDataUpdated);    
    Proxy.GetEventSink().observe(UPLATFORM.VAULTSTORAGE.DATASAVEREQUEST, _OnDataSaveRequest);
    Proxy.GetEventSink().observe(UPLATFORM.VAULTSTORAGE.OPENFILENAMEREQUEST, _OnOpenFileNameRequest);
    Proxy.GetEventSink().observe(UPLATFORM.VAULTSTORAGE.MANAGEMENTREQUEST, _DoManagement);
    _OnDataUpdated();
    
    // Save dialog
    if (typeof _options.SaveDialog != "object") {
      _options.SaveDialog = new Knowmax.SimpleDialog.Add({Element: _options.SaveDialogDivPanel,
        Modal: true, ModalShowDuration: 0.1, Window: Proxy.GetContext()});                        
    }        
    var commandlist = _options.SaveDialog.GetOptions().Element.select(".command");
    commandlist.each(function(command) {
      Event.observe(command, "click", _OnSaveDialogCommand);        
    });

    // Save As dialog
    if (typeof _options.SaveAsDialog != "object") {
      _options.SaveAsDialog = new Knowmax.SimpleDialog.Add({Element: _options.SaveAsDialogDivPanel,
        Modal: true, ModalShowDuration: 0.1, Window: Proxy.GetContext()});                        
    }
    commandlist = _options.SaveAsDialog.GetOptions().Element.select(".command");
    commandlist.each(function(command) {
      Event.observe(command, "click", _OnSaveAsDialogCommand);        
    });     
    
    // Open dialog
    if (typeof _options.OpenDialog != "object") {
      _options.OpenDialog = new Knowmax.SimpleDialog.Add({Element: _options.OpenDialogDivPanel,
        Modal: true, ModalShowDuration: 0.1, Window: Proxy.GetContext()});                        
    }
    commandlist = _options.OpenDialog.GetOptions().Element.select(".command");
    commandlist.each(function(command) {
      Event.observe(command, "click", _OnOpenDialogCommand);        
    });
    
    // Management dialog
    if (typeof _options.ManagementDialog != "object") {
      _options.ManagementDialog = new Knowmax.SimpleDialog.Add({Element: _options.ManagementDialogDivPanel,
        Modal: true, ModalShowDuration: 0.1, Window: Proxy.GetContext()});                        
    }
    commandlist = _options.ManagementDialog.GetOptions().Element.select(".command");
    commandlist.each(function(command) {
      Event.observe(command, "click", _OnManagementDialogCommand);        
    });

    // Error dialog
    if (typeof _options.ErrorDialog != "object") {
      _options.ErrorDialog = new Knowmax.SimpleDialog.Add({Element: _options.ErrorDialogDivPanel,
        Modal: true, ModalShowDuration: 0.1, Window: Proxy.GetContext()});                        
    }    
    commandlist = _options.ErrorDialog.GetOptions().Element.select(".command");
    commandlist.each(function(command) {    
      Event.observe(command, "click", _OnErrorDialogCommand);        
    });
  }       
  
  function _OnDataUpdated(event)
  {    
    if ((event) && (event.memo.Enabled)) {    
      _UpdateCommandStatus("open", true);        
      _UpdateCommandStatus("save", event.memo.DataAware); 
      _UpdateCommandStatus("saveas", event.memo.DataAware);
      _UpdateCommandStatus("new", event.memo.DataAware);              
      _UpdateCommandStatus("management", Proxy.GetValues().Application.IsServer);
      _UpdateFileName(event.memo);      
      _UpdateHistory(event.memo);
      _DisplayError(event.memo.ErrorText);      
    } else {
      _UpdateCommandStatus("open", false);
      _UpdateCommandStatus("save", false);
      _UpdateCommandStatus("saveas", false);
      _UpdateCommandStatus("new", false);          
      _UpdateCommandStatus("management", false);
      _UpdateFileName();
      _UpdateHistory();
    }      
  }
  
  function _DisplayError(errorText)
  {
    if (typeof errorText == "string") {      
      var containerlist = _options.ErrorDialog.GetOptions().Element.select(".vaultmessage");      
      if (containerlist.length == 1) {
        containerlist.each(function(container) {
          container.innerHTML = unescape(errorText);                   
          _options.ErrorDialog.Show();
        });     
      }            
    }
  }
  
  function _UpdateHistory(vaultData)
  {
    if (Object.isElement(_options.HistoryField)) {
      if (typeof _options.HistoryMax != "number") {
        _options.HistoryMax = 5;
      }
      
      // Clean up
      Element.select(_options.HistoryField, ".command.file").each(function(element) {        
        Event.stopObserving(element, _OnHistoryFileCommand);
        Event.stopObserving(element, "mouseover", _DoCommandMouseOver);
        Event.stopObserving(element, "mouseout", _DoCommandMouseOut);                       
        element.remove();
      });      
      
      // Fill with new history items
      var element;
      if ((vaultData != null) && (vaultData.History != null)) {  
        var count = 0;      
        for (var i = 0; i < vaultData.History.length; i++) {  
          if (count >= _options.HistoryMax) {        
            break;
          } else {
            element = document.createElement("div")
            Element.extend(element);
            element.addClassName("command");
            element.addClassName("file");
            element.store("file", vaultData.History[i]);
            element.update(unescape(vaultData.History[i].Name));
            Event.observe(element, "click", _OnHistoryFileCommand);
            Event.observe(element, "mouseover", _DoCommandMouseOver);
            Event.observe(element, "mouseout", _DoCommandMouseOut);               
            _options.HistoryField.appendChild(element); 
            count++;
          }
        }        
      }
    }
  }
  
  function _OnHistoryFileCommand(event)
  {
    var file = event.element().retrieve("file");
    if ((file) && (typeof file.FileId == "string")) {      
      Proxy.GetContext().UPlatform.VaultStorage.Open(unescape(file.FileId));      
    }
  }
  
  function _UpdateFileName(vaultData)
  {    
    if (Object.isElement(_options.NameField)) {      
      var filename = "";
      if (vaultData != null) {
        if (typeof vaultData.UnknownFileName == "string") {
          filename = unescape(vaultData.UnknownFileName);     
        }
      
        if (typeof vaultData.DisplayFileName == "string") {
          filename = vaultData.DisplayFileName;
        } else if (typeof vaultData.FileName == "string") {
          filename = vaultData.FileName;
        }               
        
        if (vaultData.Dirty) {
          filename = filename + '*';
        }
      }
      
      _options.NameField.innerHTML = unescape(filename);
    }
  }
  
  function _OnSaveDialogCommand(event)
  {    
    _options.SaveDialog.Hide();
    if (_dataSaveRequestData) {
      if (Element.hasClassName(event.element(), "yes")) {        
        _DoSave(_dataSaveRequestData.CallBack);        
      } else if (Element.hasClassName(event.element(), "no")) {        
        _dataSaveRequestData.CallBack();        
      } /*else if (Element.hasClassName(event.element(), "cancel")) { 
        
      }  */    
      _dataSaveRequestData = null;
    }
  }
  
  function _OnSaveAsDialogCommand(event)
  {
    _options.SaveAsDialog.Hide();
  }
  
  function _OnErrorDialogCommand(event)
  {
    _options.ErrorDialog.Hide();
  }
  
  function _OnOpenDialogCommand(event)
  {
    _options.OpenDialog.Hide();
  }
  
  function _OnManagementDialogCommand(event)
  {
    _options.ManagementDialog.Hide();
  }
  
  function _OnOpenFileNameRequest(event)
  {
    _openFileNameRequestData = event.memo;
		if (Proxy.GetValues().Application.IsClient) {
      if ((_openFileNameRequestData != null) &&
          (Object.isFunction(_openFileNameRequestData.CallBack))) {
        _FileNameRequest("open", function(result) { 
          if (result.responseJSON.Selected) {
            _openFileNameRequestData.CallBack(unescape(result.responseJSON.FileName));
          }
          _openFileNameRequestData = null;        
        });
      }
		} else {
      Proxy.GetContext().UPlatform.VaultStorage.KeyRequest(_OnLoadOpenDialog); 
	  }
  }
	
	function _FileNameRequest(dialogType, afterMethod)
	{
	  // Only in use for standalone versions!
		if (Object.isFunction(afterMethod)) {
		  if ((typeof dialogType != "string") || (dialogType != "save")) {
			  dialogType = "open";
			}
      var list = new Hash({ "sid": Proxy.GetValues().User.Sid, 
        "kmmagmaplatformrequesttype": "vaultfiledialog", "type": dialogType,
        "datatype": "xform" });	
		
      try { 
        new Ajax.Request(Proxy.GetValues().Application.Module,
        { method: 'post',
          evalJSON: true,
          parameters: list.toQueryString(),
          onSuccess: afterMethod
        });		  
      } catch(ex) {      
      } 		
		}
	}
  
  function _OnLoadOpenDialog(request)
  {
    var framelist = _options.OpenDialog.GetOptions().Element.select(".vault");
    if (framelist.length == 1) {
      framelist.each(function(frame) {
        if  (!_loadDialogLoadedRegistered) {
          _loadDialogLoadedRegistered = true;
          Event.observe(frame, "load", _OnOpenDialogLoaded);          
        }
        _options.OpenDialog.Show(); 
        frame.src = request.Url + "/Management.aspx?" + request.Parameters + "&dialogmode=fileopen&language=" +
          Proxy.GetValues().Application.Language.Id;                
      });     
    }    
  }
  
  function _OnOpenDialogLoaded(event)
  {
    var framelist = _options.OpenDialog.GetOptions().Element.select(".vault");
    if (framelist.length == 1) {
      framelist.each(function(frame) {        
        var framedocument = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;      
        if ((framedocument) && (framedocument.$)) {        
          var sink = framedocument.$("Sink");        
          if (sink) {
            sink.observe("vault:fileselectdialogexecuted", _OnOpenDialogExecuted);                  
          }
        }
      });  
    }    
  }
  
  function _OnOpenDialogExecuted(event)
  {
    _options.OpenDialog.Hide();

    var dialogresult = null;    
    var framelist = _options.OpenDialog.GetOptions().Element.select(".vault");    
    if (framelist.length == 1) {
      framelist.each(function(frame) {               
        var framedocument = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;      
        if ((framedocument) && (framedocument.$)) {        
          var sink = framedocument.$("Sink");        
          if (sink) {
            sink.stopObserving("vault:fileselectdialogexecuted", _OnOpenDialogExecuted);   
            dialogresult = {
              Result: framedocument.$("DialogResult").value,
              FolderId: framedocument.$("DialogFolderId").value, 
              FileName: framedocument.$("DialogFileName").value,
              FileId: framedocument.$("DialogFileId").value
            };
          }
        }
      });   
    }      
    
    if ((dialogresult != null) && (dialogresult.Result == "true") &&
        (_openFileNameRequestData != null) &&
        (Object.isFunction(_openFileNameRequestData.CallBack))) { 
      _openFileNameRequestData.CallBack(dialogresult.FileId);    
    }       
          
    _openFileNameRequestData = null;  
  }
  
  // Event catched to warn user about eminent data loss and allows user
  // to save data first before continuing action.
  function _OnDataSaveRequest(event)
  {   
    _dataSaveRequestData = event.memo;
    _options.SaveDialog.Show();
  }
    
  function _DoSave(afterSave)
  {
    var vaultdata = Proxy.GetContext().UPlatform.VaultStorage.GetVaultData();
    if (vaultdata != null) {      
      if ((vaultdata.FileName != null) && (vaultdata.FolderId != null)) {
        Proxy.GetContext().UPlatform.VaultStorage.Save(
          vaultdata.FolderId, vaultdata.FileName, afterSave);  
      } else {        
        _DoSaveAs(afterSave);
      }
    }
  }
  
  function _DoSaveAs(afterSave)
  {
    _afterSaveMethod = afterSave;  
    
    if (Proxy.GetValues().Application.IsClient) {           
      _FileNameRequest("save", function(result) { 
        if (result.responseJSON.Selected) {
          Proxy.GetContext().UPlatform.VaultStorage.Save(
            unescape(result.responseJSON.FolderId), 
            unescape(result.responseJSON.FileId), _afterSaveMethod);                    
        }
        _afterSaveMethod = null;        
      });
    } else {
      Proxy.GetContext().UPlatform.VaultStorage.KeyRequest(_OnLoadSaveAsDialog);    
    }
  }
  
  function _OnLoadSaveAsDialog(request)
  {    
    var framelist = _options.SaveAsDialog.GetOptions().Element.select(".vault");
    if (framelist.length == 1) {
      framelist.each(function(frame) {
        if (!_saveDialogLoadedRegistered) {
          _saveDialogLoadedRegistered = true;
          Event.observe(frame, "load", _OnSaveAsDialogLoaded);
        }
        _options.SaveAsDialog.Show();
        frame.src = request.Url + "/Management.aspx?" + request.Parameters + "&dialogmode=filesave&language=" +
          Proxy.GetValues().Application.Language.Id;                
      });     
    }  
  }
  
  function _OnSaveAsDialogLoaded()
  {
    var framelist = _options.SaveAsDialog.GetOptions().Element.select(".vault");
    if (framelist.length == 1) {
      framelist.each(function(frame) {        
        var framedocument = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;      
        if ((framedocument) && (framedocument.$)) {        
          var sink = framedocument.$("Sink");        
          if (sink) {
            sink.observe("vault:fileselectdialogexecuted", _OnSaveAsDialogExecuted);
          }
        }
      });  
    }           
  }
  
  function _OnSaveAsDialogExecuted(event)
  {
    _options.SaveAsDialog.Hide();

    var dialogresult = null;    
    var framelist = _options.SaveAsDialog.GetOptions().Element.select(".vault");    
    if (framelist.length == 1) {
      framelist.each(function(frame) {               
        var framedocument = (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;      
        if ((framedocument) && (framedocument.$)) {        
          var sink = framedocument.$("Sink");        
          if (sink) {
            sink.stopObserving("vault:fileselectdialogexecuted", _OnSaveAsDialogExecuted);          
            dialogresult = {
              Result: framedocument.$("DialogResult").value,
              FolderId: framedocument.$("DialogFolderId").value, 
              FileName: framedocument.$("DialogFileName").value
            };
          }
        }
      });   
    }      
    
    if ((dialogresult != null) && (dialogresult.Result == "true")) {            
      Proxy.GetContext().UPlatform.VaultStorage.Save(
        dialogresult.FolderId, dialogresult.FileName, _afterSaveMethod);           
    }       
          
    _afterSaveMethod = null;
  }
  
  function _DoManagement()
  {
    Proxy.GetContext().UPlatform.VaultStorage.KeyRequest(_OnLoadManagementDialog);    
  }  
  
  function _OnLoadManagementDialog(request)
  {    
    var framelist = _options.ManagementDialog.GetOptions().Element.select(".vault");    
    if (framelist.length == 1) {
      framelist.each(function(frame) {
        if (!_managementDialogLoadedRegistered) {
          _managementDialogLoadedRegistered = true;
          Event.observe(frame, "load", _OnManagementDialogLoaded);
        }
        _options.ManagementDialog.Show();
        frame.src = request.Url + "/Management.aspx?" + request.Parameters + "&language=" +
          Proxy.GetValues().Application.Language.Id;                
      });     
    }  
  }  
  
  function _OnManagementDialogLoaded()
  {
    /* Not implemented for this dialog */    
  }  
  
  function _OnExecuteCommand(event)
  {     
    var command;
    
    if (Element.hasClassName(event.element(), "open")) {
      command = "open";
      Proxy.GetContext().UPlatform.VaultStorage.Open();
    } else if (Element.hasClassName(event.element(), "save")) {
      command = "save";
      _DoSave();
    } else if (Element.hasClassName(event.element(), "saveas")) {
      command = "saveas";
      _DoSaveAs();
    } else if (Element.hasClassName(event.element(), "new")) {
      command = "new";
      Proxy.GetContext().UPlatform.VaultStorage.New();
    } else if (Element.hasClassName(event.element(), "management")) {
      command = "management";      
      _DoManagement();
      //Proxy.GetContext().UPlatform.VaultStorage.DataDirty();             
    }  
    
    Proxy.GetEventSink().fire(UPLATFORM.VAULTSTORAGE.COMMANDEXECUTED, command);    
  }
  
  function _UpdateCommandStatus(commandId, enabled)
  {
    var commandlist = Element.select(_options.Element, ".command." + commandId);
    commandlist.each(function(command) {
      if (enabled) {
        _SwapClasses(command, "disabled", "enabled");
        Event.observe(command, "click", _OnExecuteCommand);
        Event.observe(command, "mouseover", _DoCommandMouseOver);
        Event.observe(command, "mouseout", _DoCommandMouseOut);              
      } else {
        _SwapClasses(command, "enabled", "disabled");
        Event.stopObserving(command, "click", _OnExecuteCommand);
        Event.stopObserving(command, "mouseover", _DoCommandMouseOver);
        Event.stopObserving(command, "mouseout", _DoCommandMouseOut);                      
      }
    });       
  }
  
  function _DoCommandMouseOver(event)  
  {
    _UpdateCommandOverClass(event.element(), true);
  }
  
  function _DoCommandMouseOut(event)
  {
    _UpdateCommandOverClass(event.element(), false);
  }
  
  function _UpdateCommandOverClass(element, overNode)
  {     
    if ((Object.isElement(element)) && (typeof overNode == "boolean")) {  
      if (overNode) {
        Element.addClassName(element, "over");   
      } else {
        Element.removeClassName(element, "over");
      }            
    }
  }   
  
  function _SwapClasses(element, oldClass, newClass)
  {
    if ((element) && (oldClass) && (newClass)) {
      Element.removeClassName(element, oldClass);      
      Element.addClassName(element, newClass);         
      
      var list = Element.select(element, "." + oldClass);        
      list.each(function(e) {              
        Element.removeClassName(e, oldClass);      
        Element.addClassName(e, newClass);                 
      });    
    }
  }   
}

function KMUPlatformReleaseListUI(list, host, restartOnChange, errorField)
{
  // Supports release list
  var _listUI = null;  
  var _errorField = $(errorField);
  var _restartOnChange = restartOnChange;
  if (typeof _restartOnChange != "boolean") {
    _restartOnChange = true;
  }  
  this.ListUI = _listUI;
  
  _Initialize(list, host);
  
  function _Initialize(list, host)
  {      
    _listUI = new KMMagmaPlatformDeltaListUI({Id: "releases", List: list, 
      UpdateEventId: null, Host: host});      
    _listUI.SetOnItemSelected(_OnItemSelected);            
    _listUI.SetOnItemCommand(_OnItemCommand);  

    host.Proxy.GetEventSink().observe(UPLATFORM.RELEASE.CHANGED, _OnReleaseChanged);
    host.Proxy.GetEventSink().observe(UPLATFORM.RELEASE.CHANGEFAILED, _OnReleaseChangeFailed);
    host.Proxy.GetEventSink().observe(MAGMA.EVENT.APPLICATION.START, _OnApplicationStart);
  }
  
  function _OnApplicationStart()
  {    
    _listUI.SetSelected(Proxy.GetContext().UPlatform.Release.CurrentRelease().Id);
  }
  
  function _OnItemSelected(item)
  {    
    if ((item) && (Object.isElement(item.Element))) {      
      Proxy.GetContext().UPlatform.Release.Select(item.Id);
    }   
  }
  
  function _OnItemCommand(command, item)
  {    

  }
  
  function _OnReleaseChanged()
  {      
    if (_restartOnChange) {
      Proxy.Application.Reload();
    }    
  }
  
  function _OnReleaseChangeFailed(event)
  {
    if ((event) && (event.memo) && (Object.isElement(_errorField))) {
      _errorField.innerHTML = unescape(event.memo);
      Element.show(_errorField);
    } 
  }  
}

function KMUPlatformLibraryTreeUI(deltaFrame, treeNavigation)
{
  // Component to support library tree, inherited from KMUPlatformTreeUI  
  var _treeNavigation = $(treeNavigation);  
  KMUPlatformTreeUI.apply(this, ['librarytoc', deltaFrame]);
  var me = this;  
     
  _Create();
  
  function _Create()
  {               
    me.SetOnDoSelectNode(_OnDoSelectNode);
    Proxy.GetEventSink().observe(UPLATFORM.FAVORITESUPDATED, _OnLibraryTreeNeedsUpdate);        
    Proxy.GetEventSink().observe(UPLATFORM.RELEASE.LIBRARYCHANGED, _OnLibraryTreeNeedsUpdate);        
    Proxy.GetEventSink().observe("magma:librarytocnavigationupdate", _OnTreeNavigationUpdate); 
  } 

  function _OnTreeNavigationUpdate(event)
  {     
    if (Object.isElement(_treeNavigation)) {
      _treeNavigation.innerHTML = "";
      if ((event) && (event.memo) && (event.memo.Parameters) && 
          (event.memo.Parameters.History)) { 
        if ((event.memo.HasData) && (event.memo.Source)) {
          var delta = event.memo.Source.$(event.memo.Id);
          if (delta) {
            _treeNavigation.innerHTML = delta.innerHTML; 
          }        
        }
        /*  
        if (event.memo.Parameters.History.length < 1) {
          _treeNavigation.innerHTML = "";
        } else if (event.memo.Parameters.History.length == 1) {
          _treeNavigation.innerHTML = unescape(event.memo.Parameters.History[0].Title) + "*";
        } else {
          _treeNavigation.innerHTML = "<span onclick='LibraryTree.SelectNode(\"" +
            event.memo.Parameters.History[1].Id + "\")'>" + 
            unescape(event.memo.Parameters.History[1].Title + "</span>");            
        }*/
      }  
    }
  }
    
  function _OnLibraryTreeNeedsUpdate(event)
  {    
    if (!event.memo.InDirect) {
      me.Refresh();
    }
    
    /*
    if ((event.memo.Parameters == null) || (event.memo.Parameters.origin != "librarytree")) {      
      me.Refresh();    
    }*/
  }  
  
  function _OnDoSelectNode(request, frame, readOnly)
  {
    Proxy.GetContext().UPlatform.ExecuteOpenDocumentRequest(request, frame, readOnly);    
    return false;
  }   
}  

function KMUPlatformDocumentTreeUI(deltaFrame)
{
  // Component to support document tree, inherited from KMUPlatformTreeUI
  KMUPlatformTreeUI.apply(this, ['documenttoc', deltaFrame]);
  var me = this;
  var _alienSelectedNode = null;
  
  _Create();
  
  function _Create()
  {    
    me.SetOnDoSelectNode(_OnDoSelectNode);
    Proxy.GetEventSink().observe(UPLATFORM.RELEASE.LIBRARYCHANGED, _OnLibraryTreeNeedsUpdate);
    Proxy.GetEventSink().observe(UPLATFORM.SHOWALIENCONTENT, _OnShowAlienContent);
  }   
  
  function _OnShowAlienContent(event)
  {    
    _alienSelectedNode = me.GetSelectedNode();
    if (_alienSelectedNode) {    
      me.NeutralizeSelected();      
    }
  }
  
  function _OnLibraryTreeNeedsUpdate(event)
  {      
    if ((!event.memo.InDirect) || 
        ((event.memo.Parameters) && (event.memo.Parameters.origin == "librarytree"))) {         
      me.Refresh();    
    }    
  }

  function _OnDoSelectNode(request, frame, readOnly)
  {
    var id = request.get("select");
    if (id) {            
      var node = me.GetNode(id);            
      if ((node) && (node == _alienSelectedNode)) {        
        me.FakeSelected(node);
        Proxy.GetContext().UPlatform.UpdateContent();
        return false;
      }
    }
    _alienSelectedNode = null;
    
    Proxy.GetContext().UPlatform.ExecuteOpenDocumentRequest(request, frame, readOnly);    
    return false;
  }  
}

function KMUPlatformTreeUI(treeId, deltaFrame)
{
  // Universal component for delta tree support
  var _treeId = treeId;
  var _deltaFrame = deltaFrame; 
  var _visibleRoot = "";
  var _levelIsCustom = false;  
  var _onDoTransfer = null;
  var _onDoSelectNode = null;
  var _deltaHost = null; // internal use
  var _deltaId = null; // internal use      
  
  this.TreeId = _treeId;
  this.Initialize = _Initialize;  
  this.Transfer = _Transfer;
  this.LoadCustom = _LoadCustom;
  this.GetCustomFrame = _GetCustomFrame;
  this.ToggleNode = _ToggleNode;
  this.SelectNode = _SelectNode;
  this.OverNode = _OverNode;
  this.OutNode = _OutNode;  
  this.Clear = _Clear;
  this.Refresh = _Refresh;
  this.GetNode = _GetNode;
  this.GetSelectedNode = _GetSelectedNode;
  this.NeutralizeSelected = _NeutralizeSelected;
  this.FakeSelected = _FakeSelected;
  this.GetTreeObject = _GetTreeObject;
  this.GetDeltaFrame = _GetDeltaFrame;
  this.SetOnDoTransfer = _SetOnDoTransfer;
  this.SetOnDoSelectNode = _SetOnDoSelectNode;
  this.TransferComplete = _TransferComplete;
           
  function _SetOnDoTransfer(method)
  {
    if (Object.isFunction(method)) {
      _onDoTransfer = method;
    } else {
      _onDoTransfer = null;
    }    
  }
  
  function _SetOnDoSelectNode(method)
  {
    if (Object.isFunction(method)) {
      _onDoSelectNode = method;
    } else {
      _onDoSelectNode = null;
    }
  }
  
  function _GetDeltaFrame()
  {  
    if ((_deltaFrame == null) || (typeof _deltaFrame == "undefined")) {
      _deltaFrame = Proxy.Delta.CreateIFrame();
    }  
    return _deltaFrame;
  }
      
  function _Initialize()
  {        
    _UpdateTree();
  }
  
  function _Refresh()
  {    
    _UpdateTree();
  }
  
  function _UpdateTree(parameters, origin)
  {    
    if ((_treeId != null) && (typeof _treeId == "string")) {
      var list = new Hash({upaction: "toc", id: _treeId, 
        visibleroot: _visibleRoot, leveliscustom: _levelIsCustom});
      if (parameters != null) {
        list.update(parameters);
      }
            
      var isreadonly = (typeof parameters == "undefined");
      var shouldexecute = true;
      
      if ((Object.isFunction(_onDoSelectNode)) && 
          (typeof origin == "string") && (origin == "select")) {
        shouldexecute = _onDoSelectNode(list, _GetDeltaFrame(), isreadonly);
      }
      
      if (shouldexecute) {      
        Proxy.Delta.Execute(list, _GetDeltaFrame(), isreadonly);              
      }
    }
  }   
  
  function _ToggleNode(nodeId)
  {   
    _UpdateTree(new Hash({toggle: nodeId}));      
  }
  
  function _SelectNode(nodeId, origin)
  {    
    if ((origin == null) || (typeof origin != "string")) {
      origin = "booktoc";
    }
     
    //Proxy.GetEventSink().fire(Proxy.GetContext().UPLATFORM.TREESELECTNODE, 
    //  {NodeId: nodeId, TreeUI: this});
    _UpdateTree(new Hash({select: nodeId, origin: origin}), "select");         
  }
  
  function _OverNode(nodeId)
  {
    _UpdateNodeClassForHover(nodeId, true);    
  }
  
  function _OutNode(nodeId)
  {
    _UpdateNodeClassForHover(nodeId, false);  
  }
  
  function _UpdateNodeClassForHover(nodeId, overNode)
  {
    // Adds/removes "over" or "overselected" class to nodes span elements
    var div = $(nodeId);
    if (div) {
      var spanarray = div.getElementsByTagName("SPAN");
      for (var index = 0; index < spanarray.length; index++) {
        if (spanarray[index].id == nodeId + "_title") {              
          var classname = "over";
          if (Element.hasClassName(spanarray[index], "tts")) {                          
            classname += "selected";
          }        
          
          if (overNode) {
            Element.addClassName(spanarray[index], classname);            
          } else {
            Element.removeClassName(spanarray[index], classname);            
          }            
        }
      }
    }    
  }  
  
  function _GetTreeObject()
  {
    if (_treeId != null) {
      return $(_treeId);
    } else {
      return null;
    }
  }
  
  function _GetNode(id)
  {
    var tree = _GetTreeObject();
    if (tree) {
      if ((typeof id == "string") && (id !== "")) {
        var nodes = Element.select(tree, "div#" + id);
        if (nodes.length == 1) {
          return nodes[0];
        }
      }
    }
    
    return null;
  }
  
  function _GetSelectedNode()
  {
    var tree = _GetTreeObject();
    if (tree) {
      var nodes = Element.select(tree, "div.tn>span.tts");
      if (nodes.length == 1) {
        return nodes[0].parentNode;
      }
    }

    return null;    
  }
  
  function _FakeSelected(node)
  {
    if (node) {
      _NeutralizeSelected();
      var span = Element.select(node, "span.ttn");
      if (span.length == 1) {
        Element.removeClassName(span[0], "over");
        Element.removeClassName(span[0], "ttn");            
        Element.addClassName(span[0], "tts");
      }    
    }
  }
  
  function _NeutralizeSelected()
  {
    var selectednode = _GetSelectedNode();
    if (selectednode) {
      var span = Element.select(selectednode, "span.tts");
      if (span.length == 1) {
        Element.removeClassName(span[0], "tts");
        Element.removeClassName(span[0], "overselected");
        Element.addClassName(span[0], "ttn");            
      }
    }
  }
     
  function _GetCustomFrameId()
  {
    return "_customcontents_" + _treeId + "_";
  }
   
  function _LoadCustom(deltaHost, resource)
  {  
    var tree = _GetTreeObject();    
    if (tree) {
      if (resource !== "") {        
        _RemoveCustomFrame();
        tree.innerHTML = "<iframe id='" + _GetCustomFrameId() + 
          "' name='" + _GetCustomFrameId() + "' border='0' frameborder='0' framespacing='0' " +
          "src='" + unescape(resource) + "' style='width:100%;height:100%;'></iframe";                  
      } else {
        tree.innerHTML = "";
      }
    }      
  }
  
  function _RemoveCustomFrame()
  {
    var frame = _GetCustomFrameElement();
    if (frame) {
      frame.parentNode.removeChild(frame);      
    }
  }
  
  function _GetCustomFrame()
  {      
    var frame = _GetCustomFrameElement();
    if (frame) {      
      return (frame.contentWindow) ? frame.contentWindow : (frame.contentDocument.document) ? frame.contentDocument.document : frame.contentDocument;   
    }
  }
  
  function _GetCustomFrameElement()
  {
    var tree = _GetTreeObject();
    if (tree) {
      var nodes = Element.select(tree, "#" + _GetCustomFrameId());
      if (nodes.length == 1) {
        return nodes[0];
      }
    }   
  }
   
  function _Transfer(deltaHost, data, deltaId)
  {              
    if ((data) && (data.Parameters) && 
        (data.Parameters.VisibleRoot) && (data.Parameters.LevelIsCustom)) {
      _visibleRoot = data.Parameters.VisibleRoot;
      _levelIsCustom = data.Parameters.LevelIsCustom;
    } else {
      _visibleRoot = "";
      _levelIsCustom = false;
    }      
       
    if (deltaHost != null) {    
      // Determine value for state mutation
      var statemutation = "none";      
      if ((data) && (data.Parameters) && 
          (data.Parameters.StateMutation) && (!data.Parameters.CustomLevelLeaf)) {
        if (((data.Parameters.StateMutation == "levelup") ||
             (data.Parameters.Origin === "treepathnavigation"))  &&
             ((data.Parameters.LevelIsCustom) || (data.Parameters.OldLevelIsCustom))) {          
          statemutation = "up";
        } else if ((data.Parameters.StateMutation == "leveldown") &&
                   ((data.Parameters.LevelIsCustom) || (data.Parameters.OldLevelIsCustom))) {          
          statemutation = "down";
        }
      }               
    
      // Determine delta id
      _deltaId = _treeId;
      if ((typeof deltaId == "string") && (deltaId !== "")) {
        _deltaId = deltaId;
      }
    
      // Perform update
      var deltatree = deltaHost.$(_deltaId); 
      var tree = _GetTreeObject();
      if ((deltatree) && (tree)) {                                 
        _deltaHost = deltaHost;
      
        _RemoveCustomFrame();        
        if (Object.isFunction(_onDoTransfer)) {
          // Custom implementation should ALWAYS call TransferComplete!
          _onDoTransfer(tree, deltatree, statemutation);
        } else {                 
          tree.innerHTML = deltatree.innerHTML;                      
          _TransferComplete();         
        }        
      }
    }
  }
  
  function _TransferComplete()
  {                
    if (_deltaHost) {            
      eval("if (_deltaHost." + _deltaId + "Initialize) { _deltaHost." + _deltaId + "Initialize(); }");      
    }    
    _deltaHost = null;
    _deltaId = null;
  } 
  
  function _Clear(message)
  {
    _RemoveCustomFrame();
    var tree = _GetTreeObject();
    if (tree) {
      if (message !== "") {
        tree.innerHTML = unescape(message);
      } else {
        tree.innerHTML = "";
      }
    }
  }
}