protected GalleryContentImageModel Convert(GalleryContentImage item, int galleryID)
        {
            var model = new GalleryContentImageModel() { GalleryID = galleryID, ID = item.ID, Urls = item.EditUrls, Text = item.Name, Order = item.Order };

            if (item.ContentImage.TextContent != null)
            {
                switch (item.ContentImage.TextContent.ContentType)
                {
                    case TextContents.None:
                        model.ContentImage.TextContent = this.ObjectMapper.DoMapping<EmptyTextContentModel>(item.ContentImage.TextContent);
                        break;
                    case TextContents.QnA:
                        model.ContentImage.TextContent = this.ObjectMapper.DoMapping<QnATextContentModel>(item.ContentImage.TextContent);
                        break;
                    case TextContents.Pullquote:
                        model.ContentImage.TextContent = this.ObjectMapper.DoMapping<PullQuotedTextContentModel>(item.ContentImage.TextContent);
                        break;
                    case TextContents.BodyCopy:
                        model.ContentImage.TextContent = this.ObjectMapper.DoMapping<BodyCopyTextContentModel>(item.ContentImage.TextContent);
                        break;
                    case TextContents.CustomImage:
                        {
                            model.ContentImage = this.ObjectMapper.DoMapping<GalleryImageContentModel>(item.ContentImage);
                            model.ContentImage.TextContent = this.ObjectMapper.DoMapping<CustomImageContentModel>(item.ContentImage.TextContent);
                            break;
                        }
                    default:
                        throw new NotImplementedException();
                }

                model.ContentImage.TextContent.Height = item.ContentImage.TextContent.Size.HasValue ? item.ContentImage.TextContent.Size.Value.Height : (int?)null;
                model.ContentImage.TextContent.Width = item.ContentImage.TextContent.Size.HasValue ? item.ContentImage.TextContent.Size.Value.Width : (int?)null;
            }
            else
            {
                model.ContentImage.TextContent = new EmptyTextContentModel() { Position = null };
            }

            return model;
        }
        public HttpResponseMessage UploadGalleryImage(HttpRequestMessage message,
            [System.Web.Http.FromUri, System.ComponentModel.DataAnnotations.Required]Nullable<int> id, [System.Web.Http.FromUri]string imageID)
        {
            if (this.HttpContext.Request.Files.Count != 1)
                return this.Request.CreateResponse(HttpStatusCode.NotAcceptable, "There are no files or more then one for uploading in the request");

            if (!id.HasValue)
                throw new Exception("Target gallery is not pointed. Query strin parameter 'id' is required");

            var gallery = GalleryRuntime.GetGallery(id.Value);
            var template = GalleryRuntime.GetTemplate(gallery.TemplateID);

            string contentpath = gallery.GetContentPath();
            string rootpath = gallery.GetDevPath();

            if (!Directory.Exists(contentpath))
                Directory.CreateDirectory(contentpath);

            var file = this.HttpContext.Request.Files[0];

            //TODO: CHANGE VALIDATE LOGIC
            if (GalleryRuntime.MaxImageSize.HasValue && GalleryRuntime.MaxImageSize.Value < file.ContentLength)
                return this.Request.CreateResponse<string>(HttpStatusCode.BadRequest, string.Format("Uploading file size is {0}byte. Max file size {1}bytes is exceeded", file.ContentLength, GalleryRuntime.MaxImageSize.Value));

            if (GalleryRuntime.MinImageSize.HasValue && file.ContentLength < GalleryRuntime.MinImageSize.Value)
                return this.Request.CreateResponse<string>(HttpStatusCode.BadRequest, string.Format("Uploading file size is {0}byte. Min file size is {1}bytes", file.ContentLength, GalleryRuntime.MaxImageSize.Value));

            string filename = file.FileName;
            string filepath = Path.Combine(contentpath, filename);

            if (File.Exists(filepath))
            {
                filepath = Common.Utils.GenerateFilePathForDuplicate(filepath);
                filename = Path.GetFileName(filepath);
            }

            //try to save original image
            try
            {
                file.SaveAs(filepath);
            }
            catch (Exception ex)
            {
                this.Logger.WriteError(ex, string.Format("Uploaded file cannot be saved to '{0}'", filepath));
                return this.Request.CreateResponse(HttpStatusCode.InternalServerError);
            }
            finally
            {
                file.InputStream.Close();
            }

            //this handler return gallery relative image url
            Common.ActionHandler<string, string> gllrUrlHandler =
                delegate(string fname)
                {
                    return string.Format("{0}/{1}", Common.Utils.GetRelativePath(GalleryRuntime.GetGalleryOutputPath(id.Value), contentpath).TrimEnd('\\').Replace('\\', '/'), fname);
                };

            lock (gallery.GetSyncRoot())
            {
                var content = gallery.LoadContent(false);

                var siteUrls = new ImageUrlSet() { Original = Common.Utils.AbsoluteToVirtual(filepath, this.HttpContext) };
                var editUrls = new ImageUrlSet() { Original = Common.Utils.AbsoluteToVirtual(filepath, this.HttpContext) };
                var gllrUrls = new ImageUrlSet() { Original = gllrUrlHandler(filename) };

                string extension = Path.GetExtension(filename);
                string filenameonly = extension.Length > 0 ? filename.Remove(filename.Length - extension.Length) : filename;

                System.Drawing.Image originalImage = null;

                //TODO: Implement async image resizing for performance
                try
                {
                    originalImage = System.Drawing.Image.FromFile(filepath);

                    //resize images for development
                    {
                        string editpath = Path.Combine(contentpath, string.Format("{0}.lrgedit{1}", filenameonly, extension));
                        ResizeImage(originalImage, editpath, GalleryRuntime.EditedLargeImageSize);

                        editUrls.Large = Common.Utils.AbsoluteToVirtual(editpath, this.HttpContext);

                        content.SystemFilePathes.Add(editpath.Substring(rootpath.Length));
                    }
                    {
                        string editpath = Path.Combine(contentpath, string.Format("{0}.smledit{1}", filenameonly, extension));
                        ResizeImage(originalImage, editpath, GalleryRuntime.EditedSmallImageSize);

                        editUrls.Small = Common.Utils.AbsoluteToVirtual(editpath, this.HttpContext);

                        content.SystemFilePathes.Add(editpath.Substring(rootpath.Length));
                    }

                    //images for galleries
                    foreach (var isize in template.GallerySettings.ImageSizes)
                    {
                        switch (isize.Type)
                        {
                            case GalleryImageSizes.Small:
                                {
                                    string smallpath = Path.Combine(contentpath, string.Format("{0}.sml{1}", filenameonly, extension));
                                    ResizeImage(originalImage, smallpath, new System.Drawing.Size(isize.Width, isize.Height));

                                    siteUrls.Small = Common.Utils.AbsoluteToVirtual(smallpath, this.HttpContext);
                                    gllrUrls.Small = gllrUrlHandler(Path.GetFileName(smallpath));
                                }
                                break;
                            case GalleryImageSizes.Middle:
                                {
                                    string middlepath = Path.Combine(contentpath, string.Format("{0}.mdl{1}", filenameonly, extension));
                                    ResizeImage(originalImage, middlepath, new System.Drawing.Size(isize.Width, isize.Height));

                                    siteUrls.Middle = Common.Utils.AbsoluteToVirtual(middlepath, this.HttpContext);
                                    gllrUrls.Middle = gllrUrlHandler(Path.GetFileName(middlepath));
                                }
                                break;
                            case GalleryImageSizes.Large:
                                {
                                    string largepath = Path.Combine(contentpath, string.Format("{0}.lrg{1}", filenameonly, extension));
                                    ResizeImage(originalImage, largepath, new System.Drawing.Size(isize.Width, isize.Height));

                                    siteUrls.Large = Common.Utils.AbsoluteToVirtual(largepath, this.HttpContext);
                                    gllrUrls.Large = gllrUrlHandler(Path.GetFileName(largepath));
                                }
                                break;
                            default:
                                throw new NotImplementedException();
                        }
                    }
                }
                finally
                {
                    if (originalImage != null)
                        originalImage.Dispose();
                }

                GalleryImageBase img = null;

                try
                {
                    if (string.IsNullOrEmpty(imageID))
                    {
                        if (content.Images.Count == 0)
                        {
                            var cimg = new GalleryCoverImage()
                            {
                                ID = string.Format("gallery-image_{0}", Guid.NewGuid().ToString("N")),
                                Name = filename,
                                Order = 1,
                                ImageSource = new GalleryImageSource() { Type = ImageSourceTypes.LocalFile, Source = filepath.Substring(GalleryRuntime.GetGalleryDevPath(id.Value).Length) },
                                GalleryUrls = gllrUrls,
                                SiteUrls = siteUrls,
                                EditUrls = editUrls
                            };

                            //TODO: we can get default values from gallery template
                            cimg.Headline = new CoverTextItem() { FontSize = 40 };
                            cimg.Standfirst = new CoverTextItem() { FontSize = 12 };
                            cimg.ContentImage = new GalleryImageContent();
                            cimg.ContentImage.TextContent = new CustomImageTextContent();
                            content.Images.Add(cimg);
                            img = cimg;
                        }
                        else
                        {
                            var cimg = new GalleryContentImage()
                            {
                                ID = string.Format("gallery-image_{0}", Guid.NewGuid().ToString("N")),
                                Name = filename,
                                Order = content.Images.Count + 1,
                                ImageSource = new GalleryImageSource() { Type = ImageSourceTypes.LocalFile, Source = filepath.Substring(GalleryRuntime.GetGalleryDevPath(id.Value).Length) },
                                GalleryUrls = gllrUrls,
                                SiteUrls = siteUrls,
                                EditUrls = editUrls
                            };
                            cimg.ContentImage = new GalleryImageContent();
                            cimg.ContentImage.TextContent = new EmptyTextContent();

                            content.Images.Add(cimg);
                            img = cimg;
                        }
                    }
                    else if (content.Images.Count != 0)
                    {
                        if (content.CoverImage.ID == imageID)
                        {
                            content.CoverImage.Name = filename;
                            content.CoverImage.ImageSource = new GalleryImageSource() { Type = ImageSourceTypes.LocalFile, Source = filepath.Substring(GalleryRuntime.GetGalleryDevPath(id.Value).Length) };
                            content.DeleteImages(content.CoverImage.GalleryUrls, this.HttpContext);
                            content.CoverImage.GalleryUrls = gllrUrls;
                            content.DeleteImages(content.CoverImage.SiteUrls, this.HttpContext);
                            content.CoverImage.SiteUrls = siteUrls;
                            content.DeleteImages(content.CoverImage.EditUrls, this.HttpContext);
                            content.CoverImage.EditUrls = editUrls;

                            img = content.CoverImage;
                        }
                        else
                        {
                            var item = content.Images.Where(x => x.ID == imageID).SingleOrDefault();

                            item.Name = filename;
                            item.ImageSource = new GalleryImageSource() { Type = ImageSourceTypes.LocalFile, Source = filepath.Substring(GalleryRuntime.GetGalleryDevPath(id.Value).Length) };
                            content.DeleteImages(item.GalleryUrls, this.HttpContext);
                            item.GalleryUrls = gllrUrls;
                            content.DeleteImages(item.SiteUrls, this.HttpContext);
                            item.SiteUrls = siteUrls;
                            content.DeleteImages(item.EditUrls, this.HttpContext);
                            item.EditUrls = editUrls;

                            img = item;
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    //TODO: We must synchronize file updating
                    gallery.SaveContent(content, false);
                }
                catch (Exception ex)
                {
                    this.Logger.WriteError(ex);
                    File.Delete(filepath);
                    return message.CreateResponse(HttpStatusCode.InternalServerError);
                }

                var output = new UploadedImageResponse() { GalleryID = id.Value, ID = img.ID, Urls = img.SiteUrls, EditUrls = img.EditUrls, IsCover = img is GalleryCoverImage, FileName = img.Name, ImageID = imageID };
                return message.CreateResponse<UploadedImageResponse>(HttpStatusCode.OK, output);
            }
        }