} // RenderEdit

        public override void RenderInViewMode(HtmlTextWriter writer, CmsPage page, int identifier, CmsLanguage langToRenderFor, string[] paramList)
        {
            string controlId        = "SingleImageGallery_" + page.ID.ToString() + identifier.ToString() + langToRenderFor.shortCode;
            SingleImageGalleryDb db = new SingleImageGalleryDb();
            SingleImageGalleryPlaceholderData placeholderData = db.getSingleImageGallery(page, identifier, langToRenderFor, true);

            SingleImageData[] imageDatas              = new SingleImageData[0];
            SingleImageDb     singleImageDb           = new SingleImageDb();
            List <CmsPage>    pagesToGatherImagesFrom = new List <CmsPage>();

            // -- gather images to display from selected pages

            CmsPage startPage = CmsContext.getPageById(placeholderData.PageIdToGatherImagesFrom);

            if (placeholderData.RecursiveGatherImages)
            {
                Dictionary <int, CmsPage> allPages = startPage.getLinearizedPages();
                pagesToGatherImagesFrom = new List <CmsPage>(allPages.Values);
            }
            else
            {
                pagesToGatherImagesFrom.Add(startPage);
            }

            imageDatas = singleImageDb.getSingleImages(pagesToGatherImagesFrom.ToArray(), langToRenderFor);

            imageDatas = filterOutDuplicateImagePaths(placeholderData, imageDatas);
            imageDatas = filterImagesByRequiredTags(placeholderData, imageDatas);
            imageDatas = sortByPageOrder(placeholderData, imageDatas, pagesToGatherImagesFrom.ToArray());


            // -- override the full-sized display

            int imgIdToView = PageUtils.getFromForm("galleryimage", Int32.MinValue);

            if (imgIdToView >= 0)
            {
                foreach (SingleImageData i in imageDatas)
                {
                    if (i.SingleImageId == imgIdToView)
                    {
                        writer.Write(renderSinglePageDisplayOfImage(placeholderData, i, imageDatas, pagesToGatherImagesFrom.ToArray()));
                        return;
                    }
                } // foreach
            }
            else
            {
                writer.Write(getGalleryView(placeholderData, imageDatas, pagesToGatherImagesFrom.ToArray(), langToRenderFor));
            }
        } // RenderView
        public override void RenderInEditMode(HtmlTextWriter writer, CmsPage page, int identifier, CmsLanguage langToRenderFor, string[] paramList)
        {
            string controlId        = "SingleImageGallery_" + page.ID.ToString() + identifier.ToString() + langToRenderFor.shortCode;
            SingleImageGalleryDb db = new SingleImageGalleryDb();
            SingleImageGalleryPlaceholderData placeholderData = db.getSingleImageGallery(page, identifier, langToRenderFor, true);

            string[] possibleTags = (new SingleImageDb()).getAllPossibleTags();

            string action = PageUtils.getFromForm(controlId + "_action", "");

            if (action == "updateSingleImageGallery")
            {
                placeholderData.PageIdToGatherImagesFrom = PageUtils.getFromForm(controlId + "PageIdToGatherImagesFrom", placeholderData.PageIdToGatherImagesFrom);
                placeholderData.RecursiveGatherImages    = PageUtils.getFromForm(controlId + "RecursiveGatherImages", placeholderData.RecursiveGatherImages);

                placeholderData.ThumbImageDisplayBoxWidth = PageUtils.getFromForm(controlId + "ThumbnailDisplayBoxWidth", placeholderData.ThumbImageDisplayBoxWidth);

                placeholderData.ThumbImageDisplayBoxHeight = PageUtils.getFromForm(controlId + "ThumbnailDisplayBoxHeight", placeholderData.ThumbImageDisplayBoxHeight);

                placeholderData.OverrideFullDisplayBoxSize = PageUtils.getFromForm(controlId + "OverrideFullDisplayBoxSize", false);

                placeholderData.FullSizeDisplayBoxWidth = PageUtils.getFromForm(controlId + "FullSizeDisplayBoxWidth", placeholderData.FullSizeDisplayBoxWidth);

                placeholderData.FullSizeDisplayBoxHeight = PageUtils.getFromForm(controlId + "FullSizeDisplayBoxHeight", placeholderData.FullSizeDisplayBoxHeight);

                placeholderData.NumThumbsPerRow = PageUtils.getFromForm(controlId + "NumThumbsPerRow", placeholderData.NumThumbsPerRow);

                placeholderData.NumThumbsPerPage = PageUtils.getFromForm(controlId + "NumThumbsPerPage", placeholderData.NumThumbsPerPage);

                placeholderData.TagsImagesMustHave = PageUtils.getFromForm(controlId + "Tags");

                db.saveUpdatedSingleImageGallery(page, identifier, langToRenderFor, placeholderData);
            }

            Dictionary <int, CmsPage> allPages = CmsContext.HomePage.getLinearizedPages();

            NameValueCollection pageSelection = new NameValueCollection();

            foreach (int pageId in allPages.Keys)
            {
                pageSelection.Add(pageId.ToString(), allPages[pageId].getPath(langToRenderFor));
            }


            StringBuilder html = new StringBuilder();

            html.Append("<table>" + Environment.NewLine);

            html.Append("<tr>");
            html.Append("<td>Gather images from page:</td>");
            html.Append("<td>" + PageUtils.getDropDownHtml(controlId + "PageIdToGatherImagesFrom", controlId + "PageIdToGatherImagesFrom", pageSelection, placeholderData.PageIdToGatherImagesFrom.ToString()) + "</td>");
            html.Append("</tr>");

            html.Append("<tr>");
            html.Append("<td>Recursively gather images from sub-pages?</td>");
            NameValueCollection recursiveOptions = new NameValueCollection();

            recursiveOptions.Add(true.ToString(), "from the selected page and all its children");
            recursiveOptions.Add(false.ToString(), "only the selected page");
            html.Append("<td>" + PageUtils.getDropDownHtml(controlId + "RecursiveGatherImages", controlId + "RecursiveGatherImages", recursiveOptions, placeholderData.RecursiveGatherImages.ToString()) + "</td>");
            html.Append("</tr>");

            html.Append("<tr>");
            html.Append("<td>Number of thumbnails per-row:</td>");
            html.Append("<td>" + PageUtils.getInputTextHtml(controlId + "NumThumbsPerRow", controlId + "NumThumbsPerRow", placeholderData.NumThumbsPerRow.ToString(), 3, 3) + "</td>");
            html.Append("</tr>");

            html.Append("<tr>");
            html.Append("<td>Number of thumbnails per-page:</td>");
            html.Append("<td>" + PageUtils.getInputTextHtml(controlId + "NumThumbsPerPage", controlId + "NumThumbsPerPage", placeholderData.NumThumbsPerPage.ToString(), 3, 3) + "</td>");
            html.Append("</tr>");

            html.Append("<tr>");
            html.Append("<td>Thumbnail size:</td>");
            html.Append("<td>");
            html.Append(PageUtils.getInputTextHtml(controlId + "ThumbnailDisplayBoxWidth", controlId + "ThumbnailDisplayBoxWidth", placeholderData.ThumbImageDisplayBoxWidth.ToString(), 3, 4));
            html.Append(" x ");
            html.Append(PageUtils.getInputTextHtml(controlId + "ThumbnailDisplayBoxHeight", controlId + "ThumbnailDisplayBoxHeight", placeholderData.ThumbImageDisplayBoxHeight.ToString(), 3, 4));
            html.Append("</td>");
            html.Append("</tr>");


            html.Append("<tr>");
            html.Append("<td>Full-size display:</td>");
            html.Append("<td>");
            html.Append(PageUtils.getCheckboxHtml("Override full-sized display size", controlId + "OverrideFullDisplayBoxSize", controlId + "OverrideFullDisplayBoxSize", true.ToString(), placeholderData.OverrideFullDisplayBoxSize));
            html.Append("<br />");
            html.Append("Size: ");
            html.Append(PageUtils.getInputTextHtml(controlId + "FullSizeDisplayBoxWidth", controlId + "FullSizeDisplayBoxWidth", placeholderData.FullSizeDisplayBoxWidth.ToString(), 3, 4));
            html.Append(" x ");
            html.Append(PageUtils.getInputTextHtml(controlId + "FullSizeDisplayBoxHeight", controlId + "FullSizeDisplayBoxHeight", placeholderData.FullSizeDisplayBoxHeight.ToString(), 3, 4));
            html.Append("</td>");
            html.Append("</tr>");

            if (possibleTags.Length > 0)
            {
                html.Append("<tr><td>Images must be tagged with:<br />(when no tags are selected, all images are displayed)</td><td>");
                foreach (string t in possibleTags)
                {
                    if (t != "")
                    {
                        html.Append(PageUtils.getCheckboxHtml(t.Trim(), controlId + "Tags", "tag_" + t, t.Trim(), Array.IndexOf(placeholderData.TagsImagesMustHave, t) > -1));
                        html.Append("<br />");
                    }
                } // foreach

                html.Append("</td></tr>");
            }


            html.Append("</table>" + Environment.NewLine);

            html.Append(PageUtils.getHiddenInputHtml(controlId + "_action", "updateSingleImageGallery"));

            writer.Write(html.ToString());
        } // RenderEdit