[HttpPost, HttpGet] // Support GET only for testing
        public LoadFromUriResponse LoadFromUri(LoadFromUriRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.Uri == null)
            {
                throw new ArgumentException("uri must be specified");
            }

            ServiceHelper.CheckUriScheme(request.Uri);
            if (request.Options != null && request.Options.AnnotationsUri != null)
            {
                ServiceHelper.CheckUriScheme(request.Options.AnnotationsUri);
            }

            if (request.Resolution < 0)
            {
                throw new ArgumentException("Resolution must be a value greater than or equal to zero");
            }

            var cache = ServiceHelper.Cache;

            var loadOptions = new LoadDocumentOptions();

            loadOptions.Cache       = cache;
            loadOptions.UseCache    = cache != null;
            loadOptions.CachePolicy = ServiceHelper.CreatePolicy();
            loadOptions.WebClient   = null; // Use default

            if (request.Options != null)
            {
                loadOptions.DocumentId              = request.Options.DocumentId;
                loadOptions.AnnotationsUri          = request.Options.AnnotationsUri;
                loadOptions.Name                    = request.Options.Name;
                loadOptions.Password                = request.Options.Password;
                loadOptions.LoadEmbeddedAnnotations = request.Options.LoadEmbeddedAnnotations;
                loadOptions.MaximumImagePixelSize   = request.Options.MaximumImagePixelSize;
                loadOptions.FirstPageNumber         = request.Options.FirstPageNumber;
                loadOptions.LastPageNumber          = request.Options.LastPageNumber;
            }

            // Get the document name
            var documentName = request.Uri.ToString();

            // Check if this document was uploaded, then hope the user has set LoadDocumentOptions.Name to the original file name
            if (DocumentFactory.IsUploadDocumentUri(request.Uri) && !string.IsNullOrEmpty(loadOptions.Name))
            {
                // Use that instead
                documentName = loadOptions.Name;
            }

            // Most image file formats have a signature that can be used to detect to detect the type of the file.
            // However, some formats supported by LEADTOOLS do not, such as plain text files (TXT) or DXF CAD format or
            // For these, we detect the MIME type from the file extension if available and set it in the load document options and the
            // documents library will use this value if it fails to detect the file format from the data.

            if (!string.IsNullOrEmpty(documentName))
            {
                loadOptions.MimeType = RasterCodecs.GetExtensionMimeType(documentName);
            }

            LEADDocument document = null;

            try
            {
                // first, check if this is pre-cached
                if (PreCacheHelper.PreCacheExists)
                {
                    string documentId = PreCacheHelper.CheckDocument(request.Uri, loadOptions.MaximumImagePixelSize);
                    if (documentId != null)
                    {
                        var precachedDocument = DocumentFactory.LoadFromCache(cache, documentId);
                        // Instead of returning the same pre-cached document, we'll return a cloned version.
                        // This allows the user to make changes (get/set annotations) without affecting the pre-cached version.
                        document = precachedDocument.Clone(cache, new CloneDocumentOptions()
                        {
                            CachePolicy = ServiceHelper.CreatePolicy()
                        });
                    }
                }

                // else, load normally
                if (document == null)
                {
                    document = DocumentFactory.LoadFromUri(request.Uri, loadOptions);
                    if (document == null)
                    {
                        // This document was rejected due to its mimeType.
                        throw new InvalidOperationException("Document at URI '" + request.Uri + "' uses a blocked mimeType");
                    }
                }

                CacheController.TrySetCacheUri(document);

                if (ServiceHelper.AutoUpdateHistory)
                {
                    document.History.AutoUpdate = true;
                }

                ServiceHelper.SetRasterCodecsOptions(document.RasterCodecs, request.Resolution);
                document.AutoDeleteFromCache  = false;
                document.AutoDisposeDocuments = true;
                document.AutoSaveToCache      = false;
                document.SaveToCache();

                /*
                 * NOTE: Use the line below to add this new document
                 * to the pre-cache. By doing so, everyone loading a document from
                 * that URL will get a copy of the same document from the cache/pre-cache.
                 *
                 * if (!isInPrecache)
                 *  PreCacheHelper.AddExistingDocument(request.Uri, document);
                 */
                return(new LoadFromUriResponse {
                    Document = document
                });
            }
            finally
            {
                if (document != null)
                {
                    document.Dispose();
                }
            }
        }
        public SaveToCacheResponse SaveToCache(SaveToCacheRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            if (request.Descriptor == null)
            {
                throw new ArgumentNullException("Descriptor");
            }

            var cache = ServiceHelper.Cache;

            // First try to load it from the cache, if success, update it. Otherwise, assume it is not there and create a new document

            using (var document = DocumentFactory.LoadFromCache(cache, request.Descriptor.DocumentId))
            {
                if (document != null)
                {
                    // Update it
                    document.UpdateFromDocumentDescriptor(request.Descriptor);
                    document.AutoDeleteFromCache  = false;
                    document.AutoDisposeDocuments = true;
                    document.AutoSaveToCache      = false;
                    document.SaveToCache();
                    return(new SaveToCacheResponse {
                        Document = document
                    });
                }
            }

            // Above failed, create a new one.
            var createOptions = new CreateDocumentOptions();

            createOptions.Descriptor  = request.Descriptor;
            createOptions.Cache       = cache;
            createOptions.UseCache    = cache != null;
            createOptions.CachePolicy = ServiceHelper.CreatePolicy();
            using (var document = DocumentFactory.Create(createOptions))
            {
                if (document == null)
                {
                    throw new InvalidOperationException("Failed to create document");
                }

                CacheController.TrySetCacheUri(document);

                if (ServiceHelper.AutoUpdateHistory)
                {
                    document.History.AutoUpdate = true;
                }

                document.AutoDeleteFromCache  = false;
                document.AutoDisposeDocuments = true;
                document.AutoSaveToCache      = false;
                document.SaveToCache();
                return(new SaveToCacheResponse {
                    Document = document
                });
            }
        }