function Shared() { }

Shared.Resources = {};

Shared.AddResources = function(resources) { Shared.Copy(resources, Shared.Resources); };

Shared.ApplicationPreferences = {};

Shared.AddApplicationPreferences = function(preferences) { Shared.Copy(preferences, Shared.ApplicationPreferences); };

Shared.ControlClientIDs = {};

Shared.AddControlClientID = function(ids) { Shared.Copy(ids, Shared.ControlClientIDs); };

Shared.IsWindowLoaded = function(w) { return (w || window)._WindowLoaded; };

Shared.GetWindowTop = function() { return window.top; };

Shared.GetWindowOpener = function() { return window.opener; };

Shared.GetDocumentWindow = function(document) { return document.defaultView || document.parentWindow; };

Shared.GetWindowOpenerLocation = function() { return window.opener.location; };

Shared.SetWindowOpenerLocation = function(url) { (window.opener || window.top).location = url; };

Shared.ReturnOrGetElementById = function(idOrElement) { return idOrElement.tagName ? idOrElement : Shared.GetElementById(idOrElement); };

Shared.GetElementById = function(id) { return $get(id); };

Shared.GetElementsByName = function(name) { return document.getElementsByName(name); };

Shared.GetElementsByTagName = function(parent, tagName) { return parent.getElementsByTagName(tagName); };

Shared.GetFirstElementByTagName = function(parent, tagName) {
  var elements = Shared.GetElementsByTagName(parent, tagName);
  return elements.length > 0 ? elements[0] : null;
};

Shared.GetResource = function(name) { return Shared.Resources[name]; };

Shared.GetApplicationPreference = function(name) { return Shared.ApplicationPreferences[name]; };

Shared.Pluralize = function(text) {
  return text.charAt(text.length - 1) === "y" ? text.substr(0, text.length - 1) + "ies" : text + "s";
};

Shared.Format = function(format, argsOrFxn) {
  return format.replace(/(?:\{([^}]+)\})/g, typeof(argsOrFxn) === "function" ? argsOrFxn : function(str, p1) { return argsOrFxn[p1]; });
};

Shared.GetFormattedResource = function(name, argsOrFxn) {
  return Shared.Format(Shared.GetResource(name), argsOrFxn);
};

Shared.AlertResource = function(name) { alert(Shared.GetResource(name)); };

Shared.AlertFormattedResource = function(name, args) { alert(Shared.GetFormattedResource(name, args)); };

Shared.ConfirmResource = function(name) { return confirm(Shared.GetResource(name)); };

Shared.DialogResource = function(id, name) { Shared.Dialog(id, Shared.GetResource(name)); };

Shared.DialogHidden = function(id) { Shared.Dialog(id, null, true); };

Shared.DialogError = function(message) { alert(message); };

Shared.Dialog = function(id, html, hidden) {
  var dialog = Shared.GetElementById(id);
  var children = Shared.GetElementsByTagName(dialog, "div");
  children[0].style.height = Shared.GetWindowHeight() + "px";
  Shared.SetInnerHTML(children[1], html);

  dialog.style.opacity = hidden ? 0 : 1;
  dialog.style.filter = hidden ? 'alpha(opacity=0)' : null;

  Shared.SetVisible(dialog, true);
};

Shared.CloseDialog = function(id) { Shared.SetVisibleById(id, false); };

Shared.RefreshPanel = function(id) {
  var panel = ig$(id);
  Shared.SetProgressIndicatorImage(panel.getProgressIndicator());
  var orig_getCBSubmitElems = panel.getCBSubmitElems;
  panel.getCBSubmitElems = function() { return []; };
  panel.refresh();
  panel.getCBSubmitElems = orig_getCBSubmitElems;
};

Shared.SetProgressIndicatorImage = function(pi) { pi.setTemplate("<div class='wlctl_loading_label_image'><span></span></div>"); };

Shared.GetEvent = function(event) { return event ? event : window.event; };

Shared.CancelEvent = function(event) {
  event.returnValue = false;
  event.cancelBubble = true;
  if(event.preventDefault) { event.preventDefault(); }
  if(event.stopPropagation) { event.stopPropagation(); }
};

Shared.GetWindowDialogArguments = function() { return window.dialogArguments; };

Shared.SetWindowReturnValue = function(returnValue) { window.returnValue = returnValue; };

Shared.GetWindowLocation = function(w) { return (w || window).location; };

Shared.GetTopWindowLocation = function() { return window.top.location; };

Shared.GetWindowLocationSearch = function() { return Shared.GetWindowLocation().search; };

Shared.GetWindowLocationRaw = function() {
  return Shared.GetWindowLocationPath() + Shared.GetWindowLocationSearch() + "#" + Shared.GetWindowLocationHash();
};

Shared.GetWindowLocationPath = function() { return Shared.GetWindowLocation().pathname; };

Shared.SetWindowLocation = function(url, w) { (w || window).location = url; };

Shared.SetTopWindowLocation = function(url) { window.top.location = url; };

Shared.GetWindowLocationHash = function(l) {
  return ((l || location).href.split("#")[1] || "");
};

Shared.GetWindowLocationQSVars = function() {
  if(!Shared.WindowLocationQSVars) {         
    Shared.WindowLocationQSVars = Shared.GetQSVars(Shared.GetWindowLocationSearch());
  }
  return Shared.WindowLocationQSVars;
};

Shared.GetQSVars = function(search) {  
  var regexp = /[?&]+([^=]+)=([^&#$]+)/g;
  var match = null;       
  var qsVars = {};
  while ((match = regexp.exec(search))) { qsVars[match[1]] = decodeURIComponent(match[2]); }
  return qsVars;
};


Shared.SetWindowLocationHash = function(hash) { window.location.hash = hash; };

Shared.GetWindowHeight = function() {
  var height = 100;
  if(window.innerHeight) {
    height = window.innerHeight;
  } else if(document.documentElement && document.documentElement.clientHeight) {
    height = document.documentElement.clientHeight;
  } else if(document.body && document.body.clientHeight) {
    height = document.body.clientHeight;
  }
  return (isNaN(height) ? 100 : height);
};

Shared.GetWindowWidth = function() {
  var width = 100;
  if(window.innerWidth) {
    width = window.innerWidth;
  } else if(document.documentElement && document.documentElement.clientWidth) {
    width = document.documentElement.clientWidth;
  } else if(document.body && document.body.clientWidth) {
    width = document.body.clientWidth;
  }
  return (isNaN(width) ? 100 : width);
};

Shared.GetWindowValidators = function() { return window.Validators; };

Shared.HeaderHeight = 0;
Shared.FooterHeight = 0;

Shared.GetBodyHeight = function() { return Shared.GetWindowHeight() - Shared.HeaderHeight - Shared.FooterHeight; };

Shared.GetHeight = function(element) { return element.offsetHeight || 0; };

Shared.SetHeight = function(element, height) { element.style.height = (isNaN(height) ? "" : height + "px"); };

Shared.GetWidth = function(element) { return element.offsetWidth || 0; };

Shared.SetWidth = function(element, width) { element.style.width = (isNaN(width) ? "" : width + "px"); };

Shared.SetTimeout = function(code, ms) { return window.setTimeout(code, ms); };

Shared.ClearTimeout = function(id) { window.clearTimeout(id); };

Shared.CloseWindow = function(windowToClose) {
  var frame = Shared.GetFrame();
  if(frame && frame.$CloseFrame) {
    frame.$CloseFrame();
  } else {
    (windowToClose || window).close();
  }
};

Shared.GetLeft = function(width) { return (screen.width - width) / 2; };

Shared.GetTop = function(height) { return (screen.height - height) / 2; };

Shared.IsInFrame = function() { return (window.frameElement !== null); };

Shared.GetFrame = function() { return window.frameElement; };

Shared.GetFrameDocument = function(frame) {
  return frame.contentWindow.document;
};

Shared.SetTitle = function(idOrElement, text) {
  Shared.ReturnOrGetElementById(idOrElement).title = text;
};

Shared.ClearInnerHTML = function(idOrElement) {
  Shared.SetInnerHTML(idOrElement, "");
};

Shared.SetInnerHTML = function(idOrElement, html) {
  Shared.ReturnOrGetElementById(idOrElement).innerHTML = html;
};

Shared.GetInnerHTML = function(idOrElement, html) {
  return Shared.ReturnOrGetElementById(idOrElement).innerHTML;
};

Shared.SetVisible = function(element, visible) {
  if (element.style) {
    element.style.display = (visible ? "" : "none");
  } else if(element.setVisible) {
    element.setVisible(visible);
  }
};

Shared.SetVisibleById = function(id, visible) { Shared.SetVisible(Shared.GetElementById(id), visible); };

Shared.ToggleVisible = function(element) {
  Shared.SetVisible(element, !Shared.GetVisible(element));
};

Shared.ToggleVisibleById = function(id) { Shared.ToggleVisible(Shared.GetElementById(id)); };

Shared.GetVisible = function(element) {
  if(element.style) {
    return (element.style.display !== "none");
  } else if(element.setVisible) {
    return element.getVisible();
  }
};

Shared.GetVisibleById = function(id) { return Shared.GetVisible(Shared.GetElementById(id)); };

Shared.GetTargetElement = function(e) { return e.target || e.srcElement; };

Shared.OpenModalDialog = function(url, args, width, height) {
  var left = Shared.GetLeft(width);
  var top = Shared.GetTop(height);
  return window.showModalDialog(url, args, "dialogWidth:" + width + "px; dialogHeight:" + height + "px; dialogTop:" + top + "px; dialogLeft:" + left + "px; resizable:yes; scroll:yes;");
};

Shared.OpenNonModalDialog = function(url, name, width, height, popup) {
  var openUrl = Shared.GetWindowTop().$OpenUrl;
  if(openUrl) {
    var additionalProperties = {name:name};
    additionalProperties["GetMixinFor" + name] = window["GetMixinFor" + name];
    openUrl(0, {url:url, width:width, height:height, additionalProperties:additionalProperties});
    return;
  }

  var newWindow;
  name = name.replace(/-/g, "_");
  if(popup) {
    var left = Shared.GetLeft(width);
    var top = Shared.GetTop(height);
    newWindow = window.open(url, name, "channelmode=no, directories=no, fullscreen=no, location=no, menubar=no, resizable=yes, scrollbars=yes, status=yes, titlebar=yes, toolbar=no, width=" + width + ", height=" + height + ", left=" + left + ", top=" + top);
  } else {
    newWindow = window.open(url, name);
  }
  if(newWindow) {
    newWindow.focus();
  } else {
    alert("Your browser has prevented WorkLenz from opening a new window. Please enable popups for WorkLenz and re-try the operation you just performed.");
  }
  return newWindow;
};

Shared.CopyQSVariables = function(qaVarsSpec, dest) {
  var qaVars = Shared.GetWindowLocationQSVars();
  Shared.For(qaVarsSpec, function(key, value) { dest[value] = qaVars[key]; });

  var formActionVars = Shared.GetQSVars(Shared.GetForm().action);
  Shared.For(qaVarsSpec, function(key, value) { dest[value] = formActionVars[key]; });
};

Shared.PostDocumentWithParameters = function(doc, url, parameters) {
  var form = doc.createElement("form");
  form.setAttribute("action", url);
  form.setAttribute("method", "post");

  Shared.For(parameters, function(name, values) {
    if (!values.join) { values = [values]; }
    Array.forEach(values, function(value) {
      var input = doc.createElement("input");
      input.setAttribute("type", "hidden");
      input.setAttribute("name", name);
      input.setAttribute("value", value);
      form.appendChild(input);
    });
  });

  doc.body.appendChild(form);
  form.submit();
};

Shared.ActionTargetUrlSearchModifier = null;
Shared.BeforeActionTargetUrlModifier = null;

Shared.ActionTargetUrl = function(target, url, frameType, name, width, height, urlRaw, urlPath, qsvariables, controls, handlerExecuting, handlerExecuted, row, constants) {
  var urlParams = {};
  var handlerCallbackParams = {};
  if(target && typeof (target) !== "object") { target = Shared.GetElementById(target); }

  if(urlRaw) { urlParams[urlRaw] = Shared.GetWindowLocationRaw(); }
  if(urlPath) { urlParams[urlPath] = Shared.GetWindowLocationPath(); }
  if(controls) { Shared.For(controls, function(key, value) { urlParams[key] = Shared.GetValueOfControlByID(value[0], value[1]); }); }
  if(constants) { Shared.Copy(constants, urlParams); }
  if(qsvariables) { Shared.CopyQSVariables(qsvariables, urlParams); }

  if(urlRaw && Shared.ActionTargetUrlSearchModifier) { urlParams[urlRaw] = Shared.ActionTargetUrlSearchModifier(urlParams[urlRaw]); }
  if(urlRaw) { urlParams[urlRaw] = encodeURIComponent(urlParams[urlRaw]); }
  if(urlPath) { urlParams[urlPath] = encodeURIComponent(urlParams[urlPath]); }

  handlerCallbackParams.Url = url;
  handlerCallbackParams.Row = row;
  handlerCallbackParams.Params = urlParams;
  handlerCallbackParams.Target = target;

  if(handlerExecuting && handlerExecuting(handlerCallbackParams)) { return; }

  url = [handlerCallbackParams.Url];
  Shared.For(handlerCallbackParams.Params, function(key, value) { url.push("&", key, "=", value ? encodeURIComponent(value) : ""); });
  url = url.join("");

  if(Shared.BeforeActionTargetUrlModifier) { url = Shared.BeforeActionTargetUrlModifier(url); }

  var REQUEST_STYLE_SET_NAME = Shared.REQUEST_STYLE_SET_NAME;
  var styleSetName = Shared.GetWindowLocationQSVars()[REQUEST_STYLE_SET_NAME];
  if(styleSetName) {
    var styleSetNameParameters = {};
    styleSetNameParameters[REQUEST_STYLE_SET_NAME] = styleSetName;
    url = Shared.AddToUrl(url, styleSetNameParameters);
  }

  if(frameType === Shared.FRAME_TYPE_CURRENT) {
    var REQUEST_BORDER_DISPLAY_NAME = Shared.REQUEST_BORDER_DISPLAY_NAME;
    var REQUEST_BORDER_DISPLAY_NAME_NO = Shared.REQUEST_BORDER_DISPLAY_NAME_NO;
    if(Shared.GetWindowLocationQSVars()[REQUEST_BORDER_DISPLAY_NAME] === REQUEST_BORDER_DISPLAY_NAME_NO) {
      var borderDisplayParameters = {};
      borderDisplayParameters[REQUEST_BORDER_DISPLAY_NAME] = REQUEST_BORDER_DISPLAY_NAME_NO;
      url = Shared.AddToUrl(Shared.RemoveFromUrl(url, [REQUEST_BORDER_DISPLAY_NAME]), borderDisplayParameters);
    }

    if(url.length <= 2000) {
      Shared.SetWindowLocation(url);
    } else {
      var path = url.substr(0, url.indexOf("?"));
      var form = document.createElement("form");
      form.setAttribute("action", path);
      form.setAttribute("method", "post");

      Shared.For(Shared.GetQSVars(url), function(name, value) {
        var input = document.createElement("input");
        input.setAttribute("type", "hidden");
        input.setAttribute("name", name);
        input.setAttribute("value", value);
        form.appendChild(input);
      });

      document.body.appendChild(form);
      form.submit();
      document.body.removeChild(form);
    }
  } else if(frameType === Shared.FRAME_TYPE_OPENER || frameType === Shared.FRAME_TYPE_TOP) {
    var w = frameType === Shared.FRAME_TYPE_OPENER ? Shared.GetWindowOpener() : Shared.GetWindowTop();
    w.document.location = url;
    w.focus();
    if(handlerExecuted && frameType === Shared.FRAME_TYPE_OPENER) {
      handlerCallbackParams.Url = url;
      handlerCallbackParams.Window = w;
      handlerExecuted(handlerCallbackParams);
    }
  } else if(frameType === Shared.FRAME_TYPE_NEW || frameType === Shared.FRAME_TYPE_POPUP || frameType === Shared.FRAME_TYPE_EXTERNAL) {
    var popup = Shared.OpenNonModalDialog(url, name, width, height, frameType === Shared.FRAME_TYPE_POPUP);
    if(handlerExecuted) {
      handlerCallbackParams.Url = url;
      handlerCallbackParams.Window = popup;
      handlerExecuted(handlerCallbackParams);
    }
    if(frameType === Shared.FRAME_TYPE_POPUP) { return popup; }
  }else if(frameType === Shared.FRAME_TYPE_INTERNAL || frameType === Shared.FRAME_TYPE_INTERNAL_ALWAYS_VISIBLE) {
    var frames = Shared.GetElementsByName(name);
    if(frames && frames.length > 0) {
      var frame = null;
      for(var i = 0, l = frames.length; i < l; i++) { if(frames[i].src) { frame = frames[i]; break; } }
      if(frame) {
        var visible = !Shared.GetVisible(frame);
        var currentUrl = Shared.ActionTargetUrlSearchModifier ? Shared.ActionTargetUrlSearchModifier(frame.src) : frame.src;
        var newUrl = Shared.ActionTargetUrlSearchModifier ? Shared.ActionTargetUrlSearchModifier(url) : url;
        if((frameType === Shared.FRAME_TYPE_INTERNAL_ALWAYS_VISIBLE || visible) && !currentUrl.endsWith(newUrl)) {
          frame.setAttribute("origSrc", frame.src);
          frame.src = url;
        }
        if(frameType === Shared.FRAME_TYPE_INTERNAL) { Shared.SetVisible(frame, visible); }
      }
    }
  }
};

Shared.RefreshActionTargetUrl = function(name) {
  var frames = Shared.GetElementsByName(name);
  if(frames) {
    for(var i = 0, l = frames.length; i < l; i++) {
      var frame = frames[i];
      if(frame.tagName === "IFRAME") {
        var src = frame.src;
        frame.src = frame.getAttribute("origSrc");
        frame.src = src;
      }
    }
  }
};

Shared.ToServerSideDateFormat = function(value) {
  if(value && value instanceof Date && !isNaN(value.getFullYear())) { return value.format(Shared.DATE_FORMAT); }
  return "";
};

Shared.FromServerSideDateFormat = function(value) {
  if(value) { return Date.parseInvariant(value, Shared.DATE_FORMAT); }
  return null;
};

Shared.GetControlByID = function(id, controlTypeName) {
  var controlTypesByElementId = {CheckBox:1,HtmlInputHidden:1,ListBox:1,GroupedListBox:1,TextArea:1,TextBox:1,DataViewList:1,SuggestTree:1,SELECT:1,HyperLinkEdit:1,FileUpload:1,RRule:1,Expression:1};
  if (!controlTypeName || (controlTypeName in controlTypesByElementId)) {
    return Shared.GetElementById(id);
  } else if(controlTypeName === "DropDownList" || controlTypeName === "SuggestBox") {
    return igcmbo_getComboById(id);
  } else if(controlTypeName === "DateEdit") {
    return igdrp_getComboById(id);
  } else if(controlTypeName === "SelectTree") {
    return eval(id);
  } else {
    return igedit_getById(id);
  }
};

Shared.SetFocusToControlByID = function(id, controlTypeName) {
  if(controlTypeName === "HtmlInputHidden") { return false; }

  var control = Shared.GetControlByID(id, controlTypeName);
  if(!control) { return false; }
  try { (control.Object && control.Object.focus ? control.Object : control).focus(); } catch(e) { }

  return true;
};

Shared.GetDisplayValueOfControlByID = function(id, controlTypeName) {
  var control = Shared.GetControlByID(id, controlTypeName);
  
  if(!control) { return null; }
  
  if(controlTypeName === "SuggestBox") {
    return control.getDisplayValue();
  } else {
    return Shared.GetValueOfControlByID(id, controlTypeName);
  }
};

Shared.GetValueOfControl = function(control, controlTypeName, multipleValuesAsArray) {
  if(!controlTypeName) { controlTypeName = control.tagName; }
  if(controlTypeName === "CheckBox") {
    return control.checked;
  } else if(controlTypeName === "HtmlInputHidden") {
    return control.getAttribute("isdate") ? new Date(control.value) : control.value;
  } else if(controlTypeName === "ListBox" || controlTypeName === "GroupedListBox" || controlTypeName === "SELECT") {
    var value = [];
    if(control.multiple) {
      var options = control.options;
      for(var i = 0, l = control.length; i < l; i++) {
        var option = options[i];
        if(option.selected) { value.push(option.value); }
      }
    } else {
      value.push(control.value);
    }
    if(multipleValuesAsArray) { return value; }
    return value.join(";");
  } else if(controlTypeName === "DropDownList") {
    return control.getDataValue();
  } else if(controlTypeName === "TextArea" || controlTypeName === "TextBox" || controlTypeName === "INPUT" || controlTypeName === "DataViewList" || controlTypeName === "SuggestTree" || controlTypeName === "HyperLinkEdit") {
    return control.value;
  } else if(controlTypeName === "SelectTree") {
    return control[multipleValuesAsArray ? "getValues" : "getValue"]();
  } else if(controlTypeName === "SuggestBox"){
    return control._DataValueHack;
  } else if(controlTypeName === "FileUpload"){
    return control.filename;
  } else if(controlTypeName === "RRule" || controlTypeName === "Expression") {
    return control.Object.getValue();
  } else {
    return control.getValue();
  }
};

Shared.GetValueOfControlAsArray = function(control, controlTypeName) {
  var value = Shared.GetValueOfControl(control, controlTypeName, true);
  if(value === null || value === undefined) { return []; }
  return (value instanceof Array ? value : [value]);
};

Shared.GetValueOfControlByID = function(id, controlTypeName, multipleValuesAsArray) {
  var control = Shared.GetControlByID(id, controlTypeName);
  if(!control) { return null; }
  return Shared.GetValueOfControl(control, controlTypeName, multipleValuesAsArray);
};

Shared.GetAltValueOfControlByID = function(id, controlTypeName, altID) {
  var control = Shared.GetControlByID(id, controlTypeName);
  if(!control) { return null; }
  return Shared.GetAltValueOfControl(control, controlTypeName, altID);
};

Shared.GetAltValueOfControl = function(control, controlTypeName, altID) {
  if(!controlTypeName) { controlTypeName = control.tagName; }
  if(controlTypeName === "DataViewList") {
    return control.getAttribute(altID);
  } else if(controlTypeName in {ListBox:1, GroupedListBox:1, SELECT:1}){  
    return control.options[control.selectedIndex].getAttribute(altID);
  } else if(controlTypeName === "FileUpload") {
    return control.internalobject[altID];
  } else if(controlTypeName === "RRule") { 
    return control.Object.getAltValue(altID);
  } else if(control.getAttribute) {
    return control.getAttribute(altID);
  }
};

Shared.SetAltValueOfControlByID = function(id, controlTypeName, altID, value) {
  var control = Shared.GetControlByID(id, controlTypeName);
  if(control) { Shared.SetAltValueOfControl(control, controlTypeName, altID, value); }
};

Shared.SetAltValueOfControl = function(control, controlTypeName, altID, value) {
  if(!controlTypeName) { controlTypeName = control.tagName; }
  if(controlTypeName === "FileUpload") {
    control.internalobject[altID] = value;
  } else if(controlTypeName === "RRule") {
    control.Object.setAltValue(altID, value);
  } else if(control.setAttribute) {
    control.setAttribute(altID, value);
  }
};

Shared.GetAltValueOfControlByID = function(id, controlTypeName, altID) {
  var control = Shared.GetControlByID(id, controlTypeName);
  if(!control) { return null; }
  return Shared.GetAltValueOfControl(control, controlTypeName, altID);
};

Shared.SetValueOfControl = function(control, controlTypeName, value, useEditor) {
  if(!controlTypeName) { controlTypeName = control.tagName; }
  if(useEditor && control.Object && control.Object.setValue) {
    control.Object.setValue(value);
  } else if(controlTypeName === "CheckBox") {
    control.checked = value;
  } else if(controlTypeName === "HtmlInputHidden" || controlTypeName === "TextBox" || controlTypeName === "INPUT" || controlTypeName === "DataViewList" || controlTypeName === "SuggestTree") {
    control.value = value === null || value === undefined ? "" : value;
    if({DataViewList:1, SuggestTree:1}[controlTypeName] && control.onchange) { control.onchange(); }
  } else if(controlTypeName === "FileUpload") {
    control.Object.setValue(value === null || value === undefined ? "" : value);
  } else if(controlTypeName === "TextArea") {
    control.value = value === null || value === undefined ? "" : Shared.HtmlDecode(value);
  } else if(controlTypeName === "ListBox" || controlTypeName === "GroupedListBox" || controlTypeName === "SELECT") {
    if(control.tagName === "INPUT") {
      control.value = value === null || value === undefined ? "" : value;
      if(control.Object && control.Object.ElementBlurHandler) { control.Object.ElementBlurHandler(); }
    } else {
      var values = value instanceof Array ? value : (value && value.split ? Shared.HtmlDecode(value).split(";") : ((value !== null && value !== undefined) ? [value.toString()] : []));
      if(control.multiple) {
        var valueMap = {};
        Array.forEach(values, function(v) { valueMap[v] = true; });
        var options = control.options;
        for(var j = 0, l = control.length; j < l; j++) {
          var option = options[j];
          option.selected = valueMap[option.value] || false;
        }
      } else if(values.length > 0) {
        value = values[0];
        control.value = value;
        if(control.selectedIndex <= 0) {
          var controlOptions = control.options;
          for(var i = 0, len = control.length; i < len; i++) {
            var controlOption = controlOptions[i];
            if(controlOption.text === value) {
              controlOption.selected = true;
              break;
            }
          }
          if(control.selectedIndex <= 0) {
            control.selectedIndex = 0;
            control.setAttribute("ValueWasNotInList", value);
          }
        }
      } else {
        control.selectedIndex = 0;
      }
    }
  } else if(controlTypeName === "DropDownList") {
    var index = control.setDataValue(value);
    if(index === -1) { control.setSelectedIndex(0); }
  } else if(controlTypeName === "HyperLinkEdit") {
    if(value) { value = value.replace(/^[^>]+>([^<]*)[^$]+/, "$1"); }
    control.value = value;
  } else if(controlTypeName === "RRule" || controlTypeName === "Expression") {
    control.Object.setValue(value);
  } else {
    control.setValue(value);
  }
};

Shared.SetValueOfControlByID = function(id, controlTypeName, value) {
  var control = Shared.GetControlByID(id, controlTypeName);
  if(!control) { return; }
  Shared.SetValueOfControl(control, controlTypeName, value);
};

Shared.SetControlEnabled = function(control, controlTypeName, enabled) {
  if(control.tagName && {"DIV":1,"SPAN":1}[control.tagName]) { return; }
  var modCssClass = (enabled ? Shared.RemoveCssClass : Shared.AddCssClass);
  if(control.isEnabled) {
    if(control.isEnabled() !== enabled) {
      control.setEnabled(enabled);
      modCssClass(control.inputBox, "wlctl_disabled");
    }
  } else if(control.getEnabled) {
    if(control.getEnabled() !== enabled) {
      control.setEnabled(enabled);
      modCssClass(control.Element, "wlctl_disabled");
    }
  } else if(control.disabled === enabled) {
    control.disabled = !enabled;
    modCssClass(control, "wlctl_disabled");
  }
};

Shared.SetControlEnabledById = function(id, controlTypeName, enabled) {
    var control = Shared.GetControlByID(id, controlTypeName);
    if (!control) { return; }
    Shared.SetControlEnabled(control, controlTypeName, enabled);
};

Shared.SetControlReadOnly = function(control, controlTypeName, readonly) {
  if(control.setReadOnly && (control.isReadOnly ? control.isReadOnly() : control.getReadOnly()) !== readonly) {
    control.setReadOnly(readonly);
  } else if(control.readOnly !== readonly) {
    control.readOnly = readonly;
    control.disabled = readonly;
  }
};

Shared.AddHandler = function(element, eventName, handler) { $addHandler(element, eventName, handler); };

Shared.AddHandlers = function(element, events) {
  Shared.For(events, function(eventName, handler) {
    $addHandler(element, eventName, handler);
  });
};

Shared.RemoveHandler = function(element, eventName, handler) { $removeHandler(element, eventName, handler); };

Shared.RemoveHandlers = function(element, events) {
  Shared.For(events, function(eventName, handler) {
    $removeHandler(element, eventName, handler);
  });
};

Shared.AddLoadHandler = function(handler) { Shared.AddHandler(window, "load", handler); };
Shared.AddResizeHandler = function(handler) {
  var h = function() {
    if(document.body.getAttribute("noOnBodyResize")) { return; } // Hack to not call handler when IG is mucking with the DOM.
    handler.apply(this, arguments);
  };
  if(window.attachEvent) {
    (Shared.IsInFrame() && Shared.IsIE7() ? Shared.GetFrame() : window).attachEvent("onresize", h);
  } else if(window.addEventListener) {
    window.addEventListener("resize", h, false);
  }
};
Shared.AddUnloadHandler = function(handler) { Shared.AddHandler(window, "unload", handler); };
Shared.AddBeforeUnloadHandler = function(handler) { Shared.AddHandler(window, "beforeunload", handler); };

Shared.InvokeWebService = function(target, elementID, url, method, constants, qsvariables, webServiceParams, handlerCallbackParams, handlerExecuting, handlerExecuted) {
  if(!webServiceParams) { webServiceParams = {}; }
  if(!handlerCallbackParams) { handlerCallbackParams = {}; }

  handlerCallbackParams.Url = url;
  handlerCallbackParams.Method = method;
  handlerCallbackParams.Target = target;
  handlerCallbackParams.ElementID = elementID;
  handlerCallbackParams.Params = webServiceParams;

  if(constants) { Shared.Copy(constants, webServiceParams); }
  if(qsvariables) { Shared.CopyQSVariables(qsvariables, webServiceParams); }

  if(handlerExecuting && handlerExecuting(handlerCallbackParams)) { return; }

  var callbackSucceeded = null;
  var callbackFailed = null;
  if(handlerExecuted) {
    callbackSucceeded = function(result) {
      handlerCallbackParams.Succeeded = true;
      handlerCallbackParams.Result = result;
      handlerExecuted(handlerCallbackParams);
    };

    callbackFailed = function(error) {
      handlerCallbackParams.Succeeded = false;
      handlerCallbackParams.ExceptionType = error.get_exceptionType();
      handlerCallbackParams.Message = error.get_message();
      handlerCallbackParams.StackTrace = error.get_stackTrace();
      handlerCallbackParams.StatusCode = error.get_statusCode();
      handlerExecuted(handlerCallbackParams);
    };
  }

  Sys.Net.WebServiceProxy.invoke(url, handlerCallbackParams.Method, false, webServiceParams, callbackSucceeded, callbackFailed);
};

Shared.InvokeAsyncRequest = function(elementID, url, constants, qsvariables, handlerExecuting, handlerExecuted) {
  var params = {};
  if(constants) { Shared.Copy(constants, params); }
  if(qsvariables) { Shared.CopyQSVariables(qsvariables, params); }

  if(handlerExecuting && handlerExecuting({ElementID:elementID, Params:params})) { return; }

  var body = [];
  Shared.For(params, function(key, value) { body.push(key, "=", value, "&"); });
  body = body.join("");

  var webRequest = new Sys.Net.WebRequest();
  webRequest.set_url(url);
  webRequest.set_httpVerb("POST");

  webRequest.set_body(body);
  webRequest.get_headers()["Content-Length"] = body.length;
  webRequest.get_headers()["Content-Type"] = 'application/json; charset=utf-8';

  if(handlerExecuted) {
    webRequest.add_completed(
      function(executor, eventArgs) {
        handlerExecuted({
          ElementID:elementID,
          Params:params,
          IsResponseAvailable:executor.get_responseAvailable(),
          IsTimedOut:executor.get_timedOut(),
          IsAborted:executor.get_aborted(),
          StatusCode:executor.get_statusCode(),
          StatusText:executor.get_statusText(),
          Succeeded:executor.get_statusCode() === 200,
          ResponseData:executor.get_responseData()
        });
      }
    );
  }

  webRequest.invoke();
};

Shared.GetCssClass = function(element) { return element.className; };

Shared.AddCssClass = function(element, className) { Sys.UI.DomElement.addCssClass(element, className); };

Shared.RemoveCssClass = function(element, className) { Sys.UI.DomElement.removeCssClass(element, className); };

Shared.ContainsCssClass = function(idOrElement, className) { return Sys.UI.DomElement.containsCssClass(Shared.ReturnOrGetElementById(idOrElement), className); };

Shared.ToggleCssClass = function(idOrElement, className) {
  var element = Shared.ReturnOrGetElementById(idOrElement);
  var containsCssClass = Shared.ContainsCssClass(element, className);
  Shared[(containsCssClass ? "Remove" : "Add") + "CssClass"](element, className);
  return !containsCssClass;
};

Shared.ReplaceCssClass = function(element, classProperty, oldClass, newClass, reverse) {
  if(!element) { return; }
  if(!classProperty) { classProperty = "className"; }
  if(reverse) {
    var temp = oldClass;
    oldClass = newClass;
    newClass = temp;
  }
  var classString = element[classProperty];
  var oldClassRegExp = oldClass ? new RegExp("(?:^|\\s+)" + oldClass + "(?:\\s+|$)") : null;
  var newClassRegExp = newClass ? new RegExp("(?:^|\\s+)" + newClass + "(?:\\s+|$)") : null;
  var oldClassExists = oldClass ? oldClassRegExp.test(classString) : false;
  var newClassExists = newClass ? newClassRegExp.test(classString) : true;
  if(oldClassExists && newClassExists) {
    classString = classString.replace(oldClassRegExp, " ");
  } else if(oldClassExists && !newClassExists) {
    classString = classString.replace(oldClassRegExp, " " + newClass + " ");
  } else if(!oldClassExists && newClassExists) {
    /* Do nothing. */
  } else if(!oldClassExists && !newClassExists) {
    classString += " " + newClass;
  }
  element[classProperty] = classString.replace(/^\s+|\s+$/g, "");
};

Shared.For = function(object, delegate) {
  for(var key in object) { if(object.hasOwnProperty(key)) { if(delegate(key, object[key])) { return true; } } }
};

Shared.DelimitedListToObject = function(string, itemDelimiter, valueDelimiter) {
  var object = {};
  var keyValuePairs = string.split(itemDelimiter);

  Array.forEach(keyValuePairs, function(keyValuePair) {
    var keyValue = keyValuePair.split(valueDelimiter);
    object[keyValue[0]] = keyValue[1];
  });
  return object;
};

Shared.StringToObject = function(string) {
  return eval("(" + string + ")");
};

Shared.Copy = function(src, dest) { Shared.For(src, function(key, value) { dest[key] = value; }); };

Shared.CreateDelegate = function(instance, method) { return Function.createDelegate(instance, method); };

Shared.GetForm = function() { return theForm; };

Shared.GetBounds = function(element) { return Sys.UI.DomElement.getBounds(element); };

Shared.GetLocation = function(element) { return Sys.UI.DomElement.getLocation(element); };

Shared.SetLocation = function(element, x, y) { Sys.UI.DomElement.setLocation(element, x, y); };

function HandlerCollection(handlers) { this.handlers = handlers || []; }
HandlerCollection.prototype = {
  GetCount:function() { return this.handlers.length; },
  AddHandler:function(handler) { this.handlers.push(handler); },
  AddHandlers:function(handlers) { this.handlers = this.handlers.concat(handlers); },
  CallHandlers:function(content) { Array.forEach(this.handlers, function(handler) { handler(content); }); },
  RemoveHandler:function(handler) { Array.remove(this.handlers, handler); }
};

Shared.RegisterDataChangeListeners = function(keys, handler, unloadHandlerAlreadyAdded) {
  var topWindow = Shared.GetWindowTop();
  var dataChangeListeners;

  if(topWindow === window.self) {
    dataChangeListeners = (topWindow.DataChangeListeners || (topWindow.DataChangeListeners = {}));
    for(var i = 0, l = keys.length; i < l; i++) {
      var key = keys[i];
      (dataChangeListeners[key] || (dataChangeListeners[key] = new HandlerCollection())).AddHandler(handler);
    }
  } else {
    topWindow.Shared.RegisterDataChangeListeners(keys, handler, true);
    dataChangeListeners = topWindow.DataChangeListeners;
  }

  if(!unloadHandlerAlreadyAdded) {
    Shared.AddBeforeUnloadHandler(function() {
      Array.forEach(keys, function(key) {
        if(key in dataChangeListeners) {
          dataChangeListeners[key].RemoveHandler(handler);
          if(dataChangeListeners[key].GetCount() === 0) { delete dataChangeListeners[key]; }
        }
      });
    });
  }
};

Shared.CallDataChangeListeners = function(keys, eventArgs) {
  var topWindow = Shared.GetWindowTop();
  var dataChangeListeners = topWindow.DataChangeListeners;
  for (var i = 0; i < keys.length; i++) { if (keys[i] in dataChangeListeners) { dataChangeListeners[keys[i]].CallHandlers(eventArgs); } }
};

Shared.KeyboardKeyTakesSpace = function(oEvent) {
  var keyCode = oEvent.keyCode;
  
  if(oEvent.ctrlKey || oEvent.altKey) { return false; }
  if(keyCode>=37 && keyCode<=40) { return false; }  //arrow keys.
  if(keyCode===8 || keyCode===20 || keyCode===46 || keyCode===9 || keyCode===36 || keyCode===35 || keyCode===45) { return false; } //backspace=8, caps lock=20, delete=46, tab=9, home=36, end=35, insert=45
  
  return true;
};

Shared.KeyboardKeyChangesValue = function(oEvent) {
  var keyCode = oEvent.keyCode;
  
  if(keyCode>=37 && keyCode<=40) { return false; } //arrow keys.
  if(keyCode === 17 || keyCode === 18) { return false; } //ctrl = 17, alt = 18
  if(keyCode===20 || keyCode===9 || keyCode===36 || keyCode===35 || keyCode===45) { return false; } //caps lock=20, tab=9, home=36, end=35, insert=45
  
  return true;
};

Shared.ComputeDayDifference = function(dt1, dt2) {
  return Math.round((dt1.getTime() - dt2.getTime()) / (1000*60*60*24));
};

Shared.CreateActionElement = function(action, parent) {
  var element = action.Element = document.createElement("a");
  element.href = "#";
  element.title = action.Tooltip;
  element.className = action.ClassName;
  element.innerHTML = "<span>" + action.Text + "</span>";
  if(action.Name) { element.setAttribute("name", action.Name); }
  Shared.AddHandler(element, "click", action.Handler);
  if(parent) { parent.appendChild(element); }
  return element;
};

Shared.CreateActionHtml = function(buffer, href, onclick, className, title, text, textPrefix, textSuffix) {
  buffer.push('<a href="', href, '" title="', title, '"');
  if (onclick) { buffer.push(' onclick="', onclick, ';return false;"'); }
  if (className) { buffer.push(' class="', className, '"'); }
  buffer.push('>');
  if (textPrefix) { buffer.push("<span>", textPrefix, "</span>"); }
  buffer.push(text);
  if (textSuffix) { buffer.push("<span>", textSuffix, "</span>"); }
  buffer.push("</a>");
};

Shared.CreateLabelHtml = function(buffer, className, title, text, textPrefix, textSuffix) {
  buffer.push('<span title="', title, '"');
  if (className) { buffer.push(' class="', className, '"'); }
  buffer.push('>');
  if (textPrefix) { buffer.push("<span>", textPrefix, "</span>"); }
  buffer.push(text);
  if (textSuffix) { buffer.push("<span>", textSuffix, "</span>"); }
  buffer.push("</span>");
};

Shared.CreateSelectElement = function(valueList, multiple, parent, className, title, defaultValue, name) {
  var elementHTML = ["<select>"];
  Shared.For(valueList, function(i, valueItem) {
    elementHTML.push('<option value="', valueItem[0], '">', valueItem[1], '</option>');
  });
  elementHTML.push("</select>");

  var tempNode = document.createElement("div");
  tempNode.innerHTML = elementHTML.join("");
  var element = tempNode.getElementsByTagName("select")[0];

  element.multiple = multiple;
  if(name) { element.setAttribute("name", name); }
  if(title) { element.title = title; }
  if(multiple) { element.size = 5; }
  if(className) { element.className = className; }
  if(defaultValue) { element.setAttribute("defaultValue", defaultValue); }
  if(parent) { parent.appendChild(element); }
  return element;
};

Shared.CreateTextElement = function(maxLength, parent, title, name) {
  var element = document.createElement("input");
  element.type = "text";
  element.maxLength = maxLength || 255;
  if(name) { element.setAttribute("name", name); }
  if(title) { element.title = title; }
  if(parent) { parent.appendChild(element); }
  return element;
};

Shared.DataTypeIsGuid = function(key, dataType) { return key.match(/_guid$/i) && dataType === 8; };

Shared.DataTypeIsString = function(key, dataType) { return !key.match(/_guid$/i) && dataType === 8; };

Shared.DataTypeIsBoolean = function(key, dataType) { return dataType === 11; };

Shared.DataTypeIsDateTime = function(key, dataType) { return dataType === 7; };

Shared.DataTypeToDataTypeSyscode = function(key, dataType) {
  if(isNaN(dataType)) { return dataType; }
  if(Shared.DataTypeIsGuid(key, dataType)) {
    return "GUID";
  } else if(Shared.DataTypeIsString(key, dataType)) {
    return "STRING";
  } else if(Shared.DataTypeIsBoolean(key, dataType)) {
    return "BOOLEAN";
  } else if(Shared.DataTypeIsDateTime(key, dataType)) {
    return "DATETIME";
  } else {
    return "DECIMAL";
  }
};

Shared.IsGuid = function(value) { return value && value.search(/^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$/i) !== -1; };

Shared.GetFieldType = function(key) { return Shared.IsGuid(key) ? "ATTRIBUTE" : "COLUMN"; };

Shared.IsAttributeFieldType = function(key) { return Shared.GetFieldType(key) === "ATTRIBUTE"; };

Shared.GetCondition = function(key, dataType, conditionControls, fieldType, operatorValueToControlCountMap) {
  var nullString = "NULL";
  if(!fieldType) { fieldType = Shared.GetFieldType(key); }
  var operator = Shared.GetValueOfControl(conditionControls[0], conditionControls[0].tagName);
  var controlCount = operatorValueToControlCountMap[operator];
  var values = controlCount ? Shared.GetValueOfControlAsArray(conditionControls[1]) : [nullString];
  if(controlCount > 1) { values = values.concat(Shared.GetValueOfControlAsArray(conditionControls[2])); }

  if(Shared.DataTypeIsDateTime(key, dataType)) {
    var ToServerSideDateFormat = Shared.ToServerSideDateFormat;
    Array.forEach(values, function(value, i) { if(value !== nullString) { values[i] = ToServerSideDateFormat(value); } });
  }

  return {Field:key, Operator:operator, Values:values, DataTypeSyscode:Shared.DataTypeToDataTypeSyscode(key, dataType), FieldType:fieldType};
};

Shared.Serialize = function(value) { return Sys.Serialization.JavaScriptSerializer.serialize(value); };

Shared.Deserialize = function(value) { return Sys.Serialization.JavaScriptSerializer.deserialize(value); };

Shared.IsRightMouseButton = function(button) { return button === Sys.UI.MouseButton.rightButton; };

Shared.AddConditionControlsHandlerToElement = function(element, conditionControlsParent, valueToControlCountMap) {
  var handler = function(event) {
    var value = Shared.GetValueOfControl(Shared.GetTargetElement(Shared.GetEvent(event)));
    var controlCount = valueToControlCountMap[value];
    var conditionControls = conditionControlsParent.ConditionControls;
    for(var i = 1; i < conditionControls.length; i++) { Shared.SetControlEnabled(conditionControls[i], null, i <= controlCount); }
  };
  Shared.AddHandler(element, "keyup", handler);
  Shared.AddHandler(element, "change", handler);
  element.UpdateConditionControlsUI = function(el) { handler({target:el}); };
};

Shared.HasProperties = function(o) { return Shared.For(o, function() { return true; }); };

Shared.Equals = function(a, b) {
  if(!a && !b) { return true; } /* If "a" and "b" are both null or undefined they are equal. */
  if(!!a !== !!b) { return false; } /* If "a" or "b" is null or undefined and the other isn't they are not equal. */
  return !Shared.For(a, function(key, aValue) {
    var bValue = b[key];
    if(typeof(aValue) !== typeof(bValue)) { return true; }
    if(aValue instanceof Array) {
      if(aValue.length !== bValue.length) { return true; }
      for(var i = 0; i < aValue.length; i++) { if(aValue[i] !== bValue[i]) { return true; } }
    } else if(aValue !== bValue) {
      return true;
    }
  });
};

Shared.SetConditionControlValues = function(conditionControls, condition, operatorType, fieldFilterView) {
  var controlValues = condition ? condition.Values : null;
  var operatorTypeIsSelect = operatorType === fieldFilterView.OPERATOR_TYPE.SELECT || operatorType === fieldFilterView.OPERATOR_TYPE.MULTI_SELECT;
  if(controlValues) {
    if(operatorTypeIsSelect || operatorType === fieldFilterView.OPERATOR_TYPE.HIERARCHY_PARENT) {
      controlValues = [controlValues];
    } else if(operatorType === fieldFilterView.OPERATOR_TYPE.DATETIME) {
      controlValues = [Shared.FromServerSideDateFormat(controlValues[0]), Shared.FromServerSideDateFormat(controlValues[1])];
    }
  }
  Shared.SetValueOfControl(conditionControls[0], null, condition ? (operatorTypeIsSelect ? {"EqualTo":"In","NotEqualTo":"NotIn"}[condition.Operator] : null) || condition.Operator : (conditionControls[0].getAttribute("defaultValue") || ""));
  if(conditionControls.length > 1) { Shared.SetValueOfControl(conditionControls[1], null, controlValues ? controlValues[0] : null); }
  if(conditionControls.length > 2) { Shared.SetValueOfControl(conditionControls[2], null, controlValues ? controlValues[1] : null); }
};

Shared.GetAncestor = function(element, isMatch) {
  var ancestor = element.parentNode;
  while(ancestor && !isMatch(ancestor)) { ancestor = ancestor.parentNode; }
  return ancestor;
};

Shared.IsTextNode = function(element) { return element.nodeName === "#text"; };

Shared.RoundNumber = function(number, precision) {
  return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);
};

Shared.AddToUrl = function(url, pairs) {
  var hash = "";
  var hashIndex = url.indexOf("#");
  if(hashIndex !== -1) {
    hash = url.substring(hashIndex);
    url = url.substring(0, hashIndex);
  }
  var result = [url, url.indexOf("?") === -1 ? "?" : ""];
  Shared.For(pairs, function(key, value) { result.push("&", key, "=", encodeURIComponent(value)); });
  result.push(hash);
  return result.join("");
};

Shared.RemoveFromUrl = function(url, names, ignoreQSSeparatorCheck) {
  url = url.replace(new RegExp("[?&](" + names.join("|") + ")=[^&#$]*", "gi"), "");
  if (!ignoreQSSeparatorCheck && url.indexOf("?") === -1) { url = url.replace("&", "?"); }
  return url;
};

Shared.Dispose = function(obj) {
  for(var key in obj) {
    if(true) { // Hack to trick JSLint. I really want to process everything.
      var value = obj[key];
      var valueType = typeof(value);
      if(value && valueType !== "undefined" && valueType !== "string" && valueType !== "number" && valueType !== "boolean") {
        if(!value.tagName && !value.disposing && valueType !== "function") {
          try {
            value.disposing = true;
            Shared.Dispose(value);
          } catch(exc1) { }
        }

        try {
          delete obj[key];
        } catch(exc2) { }
      }
    }
  }
};

Shared.HtmlDecode = function(text) {
  if(!text) { return text; }
  return text.replace(/&([a-z]+);/gi, function(str, p1) {
    switch(p1) {
      case "lt": return '<';
      case "gt": return '>';
      case "amp": return '&';
      case "quot": return '"';
      default: return str;
    }
  });
};

Shared.HtmlEncode = function(text) {
  if(!text) { return text; }
  var splitText = text.split("");
  for(var i = 0, l = splitText.length; i < l; i++) {
    switch(splitText[i]) {
      case '<': splitText[i] = "&lt;"; break;
      case '>': splitText[i] = "&gt;"; break;
      case '&': splitText[i] = "&amp;"; break;
      case '"': splitText[i] = "&quot;"; break;
    }
  }
  return splitText.join("");
};

Shared.LoadScript = function(url, handler) {
  var scriptElement = document.createElement("script");
  scriptElement.src = url;
  scriptElement.type = "text/javascript";
  scriptElement.onload = handler;
  scriptElement.onreadystatechange = function() {
    var readyState = scriptElement.readyState;
    if(readyState === "complete" || readyState === "loaded") { handler(); }
  };
  Shared.GetElementsByTagName(document, "head")[0].appendChild(scriptElement);
};

Shared.ReloadPage = function() {  
  Shared.SetTopWindowLocation(Shared.AddToUrl(Shared.RemoveFromUrl(Shared.GetTopWindowLocation().toString(), ["rand"]), {rand:Math.random()}));
};

Shared.ReloadWindow = function(w) {
  Shared.SetWindowLocation(Shared.AddToUrl(Shared.RemoveFromUrl(Shared.GetWindowLocation(w).toString(), ["rand"]), { rand: Math.random() }), w);
};

Shared.GetCursorPosition = function(element) {
  if(document.selection) {
    var range = document.selection.createRange();
    var elementTextRange = element.createTextRange();
    var elementTextRangeCopy = elementTextRange.duplicate();
    elementTextRange.moveToBookmark(range.getBookmark());
    elementTextRangeCopy.setEndPoint('EndToStart', elementTextRange);
    return elementTextRangeCopy.text.length;
  } else {
    return element.selectionStart;
  }
};

Shared.GetActiveElement = function() {
  return document.activeElement;
};

Shared.LoadWorkspaces = function(openLastWorkspace) {
  var top = Shared.GetWindowTop();
  if(top && top.$LoadWorkspaces) {
    top.$LoadWorkspaces(openLastWorkspace);
    return 1;
  }
};

Shared.FormToMap = function(form) {
  var parameters = {};
  var formElements = form.elements;
  for(var i = 0, l = formElements.length; i < l; i++) {
    var formElement = formElements[i];
    var name = formElement.name || formElement.id;
    var tagName = formElement.tagName.toLowerCase();
    if(tagName in {input:1, textarea:1}) {
      var type = formElement.type;
      if(!type || type in {text:1, hidden:1, password:1} || (type in {checkbox:1, radio:1} && formElement.checked)) {
        parameters[name] = formElement.value;
      }
    } else if(tagName === "select") {
      var selectedOptions = Shared.GetValueOfControl(formElement, 0, 1);
      if(selectedOptions.length) { parameters[name] = selectedOptions; }
    }
  }
  return parameters;
};

Shared.MapToForm = function(parameters, form) {
  var formElements = form.elements;
  for(var i = 0, l = formElements.length; i < l; i++) {
    var formElement = formElements[i];
    var name = formElement.name || formElement.id;
    if(name in parameters) {
      var value = parameters[name];
      var tagName = formElement.tagName.toLowerCase();
      if(tagName === "select") {
        Shared.SetValueOfControl(formElement, 0, value);
      } else {
        formElement.value = value;
      }
    }
  }
};

Shared.IsIE = function() {
  var browser = Sys.Browser;
  return (browser.agent === browser.InternetExplorer);
};

Shared.IsIE7 = function() {
  var browser = Sys.Browser;
  return (browser.agent === browser.InternetExplorer && browser.version === 7);
};

String.prototype.format = function() {
/* The Resource Assignment Selector (which hasn't been converted yet) has a format string that breaks this code.
   So we'll use the old implementation until the Resource Assignment Selector is converted and the format string can be fixed.
  var args = [];
  for(var i = 0, l = arguments.length; i < l; i++) { args.push(arguments[i]); }
  return String.format(this, args);
*/
  var pattern = /\{\d+\}/g;
  var args = arguments;
  return this.replace(pattern, function(capture) { return args[capture.match(/\d+/)]; });
};

String.prototype.htmlDecode = function() {
  return Shared.HtmlDecode(this);
};

