"
            , function () { //  on Ok button pressed
                var inputBox = $("#" + formId + " input");
                var searchKey = (jQuery.trim($(inputBox).val()));
                if (!searchKey || "" == searchKey) {
                    stc.messages.errorBox("Необхідно ввести 
" + scalarSelectorLabel + "  для пошуку", function () { $(inputBox).val(""); });
                    return;
                };
                var url = http.url(http.detemplate(scalarSelectorUrlTemplate).replace("{" + scalarSelector + "}", searchKey));
                http.get(url,
                    function (response) {
                        $(foreignEntityData).html(response);
                        $(hiddenBox).val($(foreignEntityData).children(".foreignEntityId").html());
                        $(dlg).dialog("close");
                    }
                );
            }
            , null  //  on Cancel button pressed
            , { minHeight: 164, height: "auto", minWidth: 360 }
        );
    }
    /////////////////////////////
    //
    //  END OF COMMON UTILITY FUNCTIONS
    //
    /////////////////////////////
    ///////////////////////////////////////
    //
    //  FUNCTIONS TO BE EXPORTED BY MODULE
    //
    ///////////////////////////////////////
    var selectSubclassDialog = function (classTitle, subclasses, continuation) {
        var radioGroupDomId = stc.utils.getNewId();
        var radioGroupDomRef = "#" + radioGroupDomId;
        var body = "
";
        return stc.dialogs.okCancelDialog(
                    "Оберіть різновидність об'єкту класу 
" + classTitle + " "
                    , body
                    , function () {
                        var index = $(radioGroupDomRef + " input:radio[@name=restTag]:checked").val();
                        if (index) {
                            continuation(subclasses[index]);
                        }
                        else {
                            stc.messages.errorBox("Не вибрано різновидність об'єкту");
                        }
                    }
                    , null
                    , { minHeight: 160, height: "auto" }
                );
    }
    var createDialog = function (fieldSetUrl, submitUrl, classTitle, continuation) {
        return stc.dialogs.submitDialog(classTitle + " - новий об'єкт"
                , fieldSetUrl
                , function (formIdSelector) // onFieldSetLoaded
                {
                    $(formIdSelector + " .changeForeignEntityLink").each(
                        function (index, changeLink) {
                            $(changeLink).click(function (e) {
                                selectPseudoKey($("div .scalarSelector").has(changeLink));
                                return false;
                            });
                        }
                    );
                    $(formIdSelector + " .showForeignEntityLink").each(
                        function (index, changeLink) {
                            $(changeLink).click(function (e) {
                                goByPseudoKey($("div .scalarSelector").has(changeLink));
                                return false;
                            });
                        }
                    )
                }
                , "POST"
                , submitUrl
                , continuation ? continuation : function (responseText) { }
            );
    }
    var editDialog = function (fieldSetUrl, submitUrl, classTitle, continuation) {
        return stc.dialogs.submitDialog(classTitle + " - редагування"
            , fieldSetUrl
            , function (formIdSelector) // onFieldSetLoaded
            {
                $(formIdSelector + " .changeForeignEntityLink").each(
                    function (index, changeLink) {
                        $(changeLink).click(function (e) {
                            selectPseudoKey($("div .scalarSelector").has(changeLink));
                            return false;
                        });
                    }
                );
                $(formIdSelector + " .showForeignEntityLink").each(
                    function (index, changeLink) {
                        $(changeLink).click(function (e) {
                            goByPseudoKey($("div .scalarSelector").has(changeLink));
                            return false;
                        });
                    }
                )
            }
            , "PUT"
            , submitUrl
            , continuation ? continuation : function (responseText) { }
        );
    }
    ///////////////////////////////////////////////
    //
    //  This is INDEX MODE initialization function - ALSO EXPORTED
    //
    ///////////////////////////////////////////////
    var _initIndexMode = function (rootDomId, masterId, masterUrlTemplates, urlTemplates, standardJsActions, classTitle, subclasses, options) {
        standardJsActions = standardJsActions || [];
        options = options || {};
        options.RoutePrefix = options.RoutePrefix || null;
        options.Actions = options.Actions || {};
        var rootReference = "#" + rootDomId;
        ///////////////////////////////////////////////////////////
        //
        //  following are default methods for standard actions
        //
        ///////////////////////////////////////////////////////////
        var addEntity = function (cntr) {
            var subDlg;
            if (0 == subclasses.length) {
                //  entity class is concrete class - no subclass choise required
                subDlg = createDialog(cntr.fieldSetNewUrl(), cntr.createUrl(), classTitle, function (responseText) { cntr.onCreated(responseText); })
            }
            else {
                subDlg = selectSubclassDialog(classTitle, subclasses, function (subclass) { $(subDlg).dialog("close"); createDialog(cntr.fieldSetNewUrlForSubclass(subclass), cntr.createUrlForSubclass(subclass), subclass.caption, function (responseText) { cntr.onCreated(responseText); }); });
            }
        }
        var deleteEntity = function (cntr, id) {
            var classCaption = cntr.getEntityTypeCaptionRequired(id) ? cntr.getEntityTypeCaption(id) : null;
            var question = "Знищити об'єкт 
" + cntr.getEntityCaption(id) + " " + (classCaption ? " класу 
" + classCaption + " " : "") + "?";
            stc.messages.okCancelBox(null, question, { ok: "Знищити" }, function () { cntr.doDeleteEntity(id); });
        }
        var editEntity = function (cntr, id) {
            editDialog(cntr.fieldSetUrl(id), cntr.updateUrl(id), cntr.getEntityTypeCaption(id), function () { cntr.loadHtmlTable(); });
        }
        var showEntity = function (cntr, id) {
            window.location = cntr.showEntityUrl(id);
        }
        ///////////////////////////////////////////////////////////
        //
        //  end of default methods for standard actions
        //
        ///////////////////////////////////////////////////////////
        var noAction = {};  //  just an empty object whose identity is used to state that no action is required
        ////////////////////////////////////////////////////////////////////////////////////////////
        //
        //  Following are standard actions definitions
        //  The fragment is codegenerated by C:\_TRep.Net.2012\Stc.Lib\Stc.MVC\jsActions.xlsx
        //
        ////////////////////////////////////////////////////////////////////////////////////////////
        var jsaAdd = standardJsActions['jsaAdd'] || {};
        if (jsaAdd.method && 'noaction' == jsaAdd.method) {
            jsaAdd = noAction;
        }
        else {
            jsaAdd.label = !jsaAdd.label || 'default' == jsaAdd.label ? 'Додати' : jsaAdd.label;
            jsaAdd.method = !jsaAdd.method || 'default' == jsaAdd.method ? addEntity : jsaAdd.method;
            jsaAdd.buttonOptions = !jsaAdd.buttonOptions || 'default' == jsaAdd.buttonOptions ? { icons: { primary: 'ui-icon ui-icon-plusthick'}} : jsaAdd.buttonOptions;
        }
        var jsaDelete = standardJsActions['jsaDelete'] || {};
        if (jsaDelete.method && 'noaction' == jsaDelete.method) {
            jsaDelete = noAction;
        }
        else {
            jsaDelete.label = !jsaDelete.label || 'default' == jsaDelete.label ? 'Знищити' : jsaDelete.label;
            jsaDelete.method = !jsaDelete.method || 'default' == jsaDelete.method ? deleteEntity : jsaDelete.method;
            jsaDelete.buttonOptions = !jsaDelete.buttonOptions || 'default' == jsaDelete.buttonOptions ? { icons: { primary: 'ui-icon ui-icon-closethick'}} : jsaDelete.buttonOptions;
        }
        var jsaEdit = standardJsActions['jsaEdit'] || {};
        if (jsaEdit.method && 'noaction' == jsaEdit.method) {
            jsaEdit = noAction;
        }
        else {
            jsaEdit.label = !jsaEdit.label || 'default' == jsaEdit.label ? 'Редагувати' : jsaEdit.label;
            jsaEdit.method = !jsaEdit.method || 'default' == jsaEdit.method ? editEntity : jsaEdit.method;
            jsaEdit.buttonOptions = !jsaEdit.buttonOptions || 'default' == jsaEdit.buttonOptions ? { icons: { primary: 'ui-icon ui-icon-pencil'}} : jsaEdit.buttonOptions;
        }
        var jsaShow = standardJsActions['jsaShow'] || {};
        if (jsaShow.method && 'noaction' == jsaShow.method) {
            jsaShow = noAction;
        }
        else {
            jsaShow.label = !jsaShow.label || 'default' == jsaShow.label ? 'Показати' : jsaShow.label;
            jsaShow.method = !jsaShow.method || 'default' == jsaShow.method ? showEntity : jsaShow.method;
            jsaShow.buttonOptions = !jsaShow.buttonOptions || 'default' == jsaShow.buttonOptions ? { icons: { primary: 'ui-icon ui-icon-arrowreturnthick-1-e'}} : jsaShow.buttonOptions;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////
        //
        //  End of standard actions definitions
        //
        ////////////////////////////////////////////////////////////////////////////////////////////
        var cntr = {
            //  об'єкт-котролер, який містить всі утилітарні змінні та функції, корисні всередині індекс-моду
            //  ми використовуємо цей об'єкт-контролер, а не просто купу локальних змінних тому, що він є механізмом
            //  який забезпечує можливість зовнішнього перевизначення стандартних акцій
            //  фактично, він передається цим функціям у якості параметру
            masterId: masterId
            ,
            masterUrlTemplates: masterUrlTemplates
            ,
            classTitle: classTitle
            //  інші члени об'єкта встановлюються нижче
        }
        cntr.entitiesListPlaceHolderReference = rootReference + " .entitiesListPlaceholder";
        cntr.entitiesListReference = cntr.entitiesListPlaceHolderReference + " .entitiesList";
        /////////////////////////////////////
        //
        //  INDEX MODE NAVIGATION FUNCTIONS
        //
        /////////////////////////////////////
        function createIndexModeNavigation(urlTemplateName, idRequired) {
            //  допоміжна функція, яка інкорпорує параметр urlTemplates
            return createNavigation(urlTemplates, urlTemplateName, idRequired);
        }
        cntr.htmlTableUrl = createIndexModeNavigation("htmlTable", false);
        cntr.showEntityUrl = createIndexModeNavigation("show", true);
        cntr.fieldSetUrl = createIndexModeNavigation("fieldSet", true);
        cntr.updateUrl = createIndexModeNavigation("update", true);
        cntr.fieldSetNewUrl = createIndexModeNavigation("fieldSetNew", false);
        cntr.createUrl = createIndexModeNavigation("create", false);
        cntr.deleteUrl = createIndexModeNavigation("delete", true);
        cntr.fieldSetNewUrlForSubclass = function (subclass) {
            return cntr.fieldSetNewUrl() + "/" + subclass.name;
        }
        cntr.createUrlForSubclass = function (subclass) {
            var url = http.detemplate(subclass.createUrlTemplate);
            return stc.http.url(url);
        }
        /////////////////////////////////////
        //
        //  INDEX MODE INTERNAL UTILITY FUNCTIONS
        //
        /////////////////////////////////////
        function getControlCell(id) {
            var idDiv = $(cntr.entitiesListReference + " div.entityId").filter(function () { return $(this).html() == id; });
            return $(idDiv).parent();
        }
        function getEntityAttribute(id, selector) {
            //var idDiv = $(cntr.entitiesListReference + " div.entityId").filter(function () { return $(this).html() == id; });
            //return $(idDiv).siblings(selector).html();
            return $(getControlCell(id)).children(selector).html();
        }
        cntr.getEntityId = function (element) {
            //var id = $(cntr.entitiesListReference + " tr").has(element).attr("entityid");
            var id = $(cntr.entitiesListReference + " tr td").has(element).children(".entityId").html();
            return id;
        }
        cntr.getEntityCaption = function (id) {
            //var caption = $(cntr.entitiesListReference + " tr[entityid=" + id + "] div.entityCaption").html();
            //var idDiv = $(cntr.entitiesListReference + " div.entityId").filter(function () { return $(this).html() == id; });
            //var caption = $(idDiv).siblings(".entityCaption").html();
            //var caption = $(getControlCell(id)).children(".entityCaption").html();
            //return caption;
            return getEntityAttribute(id, ".entityCaption");
        }
        cntr.getEntityTypeCaption = function (id) {
            //var caption = $(cntr.entitiesListReference + " tr[entityid=" + id + "] div.entityTypeCaption").html();
            //return caption;
            return getEntityAttribute(id, ".entityTypeCaption");
        }
        cntr.getEntityTypeCaptionRequired = function (id) {
            //var required = $(cntr.entitiesListReference + " tr[entityid=" + id + "] div.entityTypeCaptionRequired").html();
            //return "true" == required;
            return "true" == getEntityAttribute(id, ".entityTypeCaptionRequired");
        }
        cntr.deleteHtmlTableRow = function (id) {
            //$(cntr.entitiesListReference + " tr[entityid=" + id + "]").remove();
            $(getControlCell(id)).parent("tr").remove();
        }
        cntr.doDeleteEntity = function (id) {
            stc.http.deleteResource(cntr.deleteUrl(id)
                , function (xhr) {  //  onSuccess
                    if (204 == xhr.status) {
                        //  204 - "NO CONTENT" status returned if resource was actually deleted
                        
                        cntr.deleteHtmlTableRow(id) //  to delete row from ui table
                    }
                    else {
                        //  other "successfull" status codes (like 200 - "OK") could be returned 
                        //  if resource wasn't acutally deleted but rather modified 
                        //  (i. e. invoice or order could be "withdrawn" but lef in DB rather then deleted from DB
                        
                        cntr.loadHtmlTable();   //  to refresh ui table data
                    }
                }
            );
        }
        cntr.loadHtmlTable = function () {
            $(cntr.entitiesListPlaceHolderReference).empty();
            $(cntr.entitiesListPlaceHolderReference).load(
                cntr.htmlTableUrl()
                , function (responseText, textStatus, xhr) {
                    if (xhr.status > 299) {
                        stc.http.defaultErrorHandler(xhr);
                    }
                    else {
                        if (jsaShow != noAction) {
                            $(cntr.entitiesListReference + " .showButton").button(jsaShow.buttonOptions).click(function (e) { jsaShow.method(cntr, cntr.getEntityId(this)); return false });
                            $(cntr.entitiesListReference + " .showLink").click(function (e) { showEntity(cntr.getEntityId(this)); return false });   //  EVEN IF SHOW ACTION IS SET TO NOACTION WE KEEP DEFAULT "SHOW" PROCESSING FOR .showLink (EVEN WHEN each .showButton removed)
                        }
                        else {
                            $(cntr.entitiesListReference + " .showButton").remove();
                            //$(entitiesListReference + " .showLink").remove();
                        }
                        if (jsaEdit != noAction) {
                            $(cntr.entitiesListReference + " .editButton").button(jsaEdit.buttonOptions).click(function (e) { jsaEdit.method(cntr, cntr.getEntityId(this)); return false });   //  "return false" prevents default event processing
                        }
                        else {
                            $(cntr.entitiesListReference + " .editButton").remove();
                        }
                        if (jsaDelete != noAction) {
                            $(cntr.entitiesListReference + " .deleteButton").button(jsaDelete.buttonOptions).click(function (e) { jsaDelete.method(cntr, cntr.getEntityId(this)); return false });   //  "return false" prevents default event processing
                        }
                        else {
                            $(cntr.entitiesListReference + " .deleteButton").remove();
                        }
                        $(".notClickable").click(function (e) { return false; });
                    }
                }
            );
        }
        cntr.onCreated =
        options.showOnCreated
            ? function (responseText) {
                //  go to url of newly created entity
                //var url = stc.http.url(responseText)
                var url = createIndexModeNavigation("show", true)(responseText);
                location = url;
            }
            : function (responseText) {
                cntr.loadHtmlTable();    //  just reload a table
            }
        //
        /////////////////////////////////////
        ///////////////////////////////////////////
        //
        //  Actual INDEX MODE initialization code
        //  starts here
        //
        ///////////////////////////////////////////
        if (jsaAdd != noAction) {
            $(rootReference + " .addButton").button(jsaAdd.buttonOptions).click(function (e) { jsaAdd.method(cntr); return false; }); //  "return true" prevents default event processing
        }
        else {
            $(rootReference + " .addButton").remove();
        }
        $(rootReference + " .backLink")
        .button({ icons: { primary: 'ui-icon-arrowreturnthick-1-w'} })
        .click(
            function (e) {
                history.back();
                return false; //  "return false" prevents default event processing
            });
        cntr.loadHtmlTable(); //  this function load 
 html and sets events handlers for its "show" "edit" and "delete" row buttons
    }
    ///////////////////////////////////////////////
    //
    //  This is SHOW MODE initialization function - ALSO EXPORTED
    //
    ///////////////////////////////////////////////
    var _initShowMode = function (rootDomId, entityId, classTitle, urlTemplates, standardJsActions, customJsActions) {
        var scntr = {
            //  об'єкт-котролер, який містить всі утилітарні змінні та функції, корисні всередині шоу-моду
            //  ми повертаємо цей об'єкт-котролер з методу initShowMode надаючи можливість іншим модулям
            //  які використовуються на сторінці звертатись до внутрішніх методів шоу-моду (поки що це лише loadDetails)
        }
        /////////////////////////////////////
        //
        //  SHOW MODE NAVIGATION FUNCTIONS
        //
        /////////////////////////////////////
        var rootReference = "#" + rootDomId;
        var createShowModeNavigation = function (urlTemplateName) {
            //  це - допоміжна функція, яка ствоюрє навігаційну функцію з урахуванням того,
            //  що в show mode навігаційні функції не вимагають параметру для ідентифікації ентіті
            return function () {
                return createNavigation(urlTemplates, urlTemplateName, true)(entityId);
            }
        }
        var entityDetailsUrl = createShowModeNavigation("entityDetails");
        var fieldSetUrl = createShowModeNavigation("fieldSet");
        var updateUrl = createShowModeNavigation("update");
        //
        /////////////////////////////////////
        /////////////////////////////////////
        //
        //  SHOW MODE INTERNAL UTILITY FUNCTIONS
        //
        /////////////////////////////////////
        scntr.getEntityCaption = function () {
            var caption = $(rootReference + " .entityCaption").html();
            return caption;
        }
        scntr.loadDetails = function () {
            $(rootReference + " .detailsPlaceholder").empty();
            $(rootReference + " .detailsPlaceholder").load(entityDetailsUrl()
            , function (responseText, textStatus, xhr) {
                if (xhr.status > 299) {
                    stc.http.defaultErrorHandler(xhr);
                }
                else {
                    $(".entityCaption").html(scntr.getEntityCaption());
                    $(".notClickable").click(function (e) { return false; });
                }
            }
            );
        }
        //
        /////////////////////////////////////
        ///////////////////////////////////////////
        //
        //  Actual SHOW MODE initialization code
        //  starts here
        //
        ///////////////////////////////////////////
        scntr.loadDetails();
        $(".customJsAction").each(function (index, e) { $(e).button().click(customJsActions[$(e).attr("actionname")].JsMethod); });
        $(".tabs").tabs();
        $(rootReference + " .editLink")
                .button({ icons: { primary: 'ui-icon-pencil'} })
                .click(
                    function (e) {
                        editDialog(fieldSetUrl(), updateUrl(), classTitle, function () { scntr.loadDetails(); })
                        return false; //  "return false" prevents default event processing
                    });
        $(rootReference + " .backLink")
                .button({ icons: { primary: 'ui-icon-arrowreturnthick-1-w'} })
                .click(
                    function (e) {
                        history.back();
                        return false; //  "return false" prevents default event processing
                    });
        return scntr;
    }
    //  END OF SHOW MODE INITIALIZATION FUNCTION
    ///////////////////////////////////////
    //
    //  HERE WE REGISTER MODULE
    //
    ///////////////////////////////////////
    STC.register(
        "dynamicUI"
        , { dummy: null
            , initShowMode: _initShowMode
            , initIndexMode: _initIndexMode
            , selectSubclassDialog: selectSubclassDialog
            , createDialog: createDialog
            , editDialog: editDialog
        }
        );
})();