@SuppressWarnings("unchecked")
  protected static void includeScriptLibraries(ScriptEngine engine) throws ScriptException {
    FacesContext context = FacesContext.getCurrentInstance();

    String language = engine.getFactory().getLanguageName();
    Set<String> mimeTypes = new HashSet<String>(engine.getFactory().getMimeTypes());
    mimeTypes.add("text/x-script-" + language);

    Set<String> includedLibraries =
        (Set<String>) getScopeMap().get("_" + language + "IncludedLibraries");
    if (includedLibraries == null) {
      includedLibraries = new HashSet<String>();
      getScopeMap().put("_" + language + "IncludedLibraries", includedLibraries);
    }

    // Now look through the view's resources for appropriate scripts and load them
    UIViewRootEx2 view = (UIViewRootEx2) context.getViewRoot();
    if (view != null) {
      for (Resource res : view.getResources()) {
        if (res instanceof ScriptResource) {
          ScriptResource script = (ScriptResource) res;
          if (script.getType() != null && mimeTypes.contains(script.getType())) {
            // Then we have a script - find its contents and run it

            String properName = (script.getSrc().charAt(0) == '/' ? "" : "/") + script.getSrc();
            if (!includedLibraries.contains(properName)) {
              InputStream is =
                  context
                      .getExternalContext()
                      .getResourceAsStream("/WEB-INF/" + language + properName);
              if (is != null) {
                engine.eval(new InputStreamReader(is));
              }

              includedLibraries.add(properName);
            }
          }
        }
      }
    }
  }
  @Override
  public void encodeBegin(FacesContext context, UIComponent component) throws IOException {

    ResponseWriter writer = context.getResponseWriter();

    UISelect2Picker picker = (UISelect2Picker) component;
    // IPickerData data = picker.getDataProvider();

    UIInputEx _for = (UIInputEx) getFor(context, picker);

    boolean readOnly = _for != null ? FacesUtil.isComponentReadOnly(context, _for) : false;

    // load select2 library and stylesheet
    ScriptResource js = new ScriptResource();
    js.setClientSide(true);
    js.setSrc("/.ibmxspres/.extlib/bootstrap/select2/select2.js");

    StyleSheetResource css = new StyleSheetResource();
    css.setHref("/.ibmxspres/.extlib/bootstrap/select2/select2.css");

    StyleSheetResource cssBootstrap = new StyleSheetResource();
    cssBootstrap.setHref("/.ibmxspres/.extlib/bootstrap/select2/select2-bootstrap.css");

    UIViewRootEx rootEx = (UIViewRootEx) context.getViewRoot();
    rootEx.addEncodeResource(js);
    rootEx.addEncodeResource(css);
    rootEx.addEncodeResource(cssBootstrap);

    if (readOnly) {

      // selected values, let's not wrap them in a frameset and table here :-)
      writer.writeText(Select2PickerRenderer.join(_for.getValueAsList(), ", "), null);

    } else {

      String id = picker.getId();

      // if we're using the search option, select2 needs to be attached to the hidden input
      if (!picker.isUseRemoteData()) {

        newLine(writer);
        writer.startElement("select", component);
        writer.writeAttribute("id", picker.getId(), null);
        writer.writeAttribute("class", "select2picker", null);

        if (StringUtil.isNotEmpty(_for.getMultipleSeparator())) {
          writer.writeAttribute("multiple", "multiple", null);
        }

        writer.endElement("select");
      }

      newLine(writer);
      writer.startElement("script", component); // $NON-NLS-1$

      // create the parameters to initialize a new select2 object
      HashMap<String, Object> params = new HashMap<String, Object>();

      params.put("id", id);
      params.put("forId", _for.getClientId(context));
      params.put("currentValue", _for.getValueAsString());
      params.put("allowMultiple", StringUtil.isNotEmpty(_for.getMultipleSeparator()));
      params.put("restUrl", picker.getUrl(context, null)); // rest service URL
      params.put("useRemoteData", picker.isUseRemoteData());
      params.put("placeHolder", picker.getPlaceHolder());
      params.put("allowClearing", picker.isAllowClearing());
      params.put("formatSelection", picker.getFormatSelection());
      params.put("formatResult", picker.getFormatResult());
      params.put("isNativeSelect", false);

      String lw = picker.getListWidth();
      if (StringUtil.isNotEmpty(lw)) {
        params.put("listWidth", lw); // $NON-NLS-1$
      }

      int maxRowCount = picker.getMaxRowCount();

      if (maxRowCount > 0) {
        params.put("maxRowCount", maxRowCount); // $NON-NLS-1$
      }

      try {
        // writer.writeText("dojo.addOnLoad( function() { initSelect2(" +
        // JsonGenerator.toJson(JsonJavaFactory.instanceEx, params) + "); } );", null);
        writer.writeText(
            "XSP.initSelect2Picker("
                + JsonGenerator.toJson(JsonJavaFactory.instanceEx, params)
                + ");",
            null);
      } catch (JsonException e) {
      }

      writer.endElement("script");
      newLine(writer);
    }
  }