private byte[] FilterRESTRequest(
            RestHandlerOpCode opCode,
            RestRequestParameters restInput,
            out string responseProperties)
        {
            try
            {
                responseProperties = null;
                IRESTRequestHandler restRequestHandler = _restServiceSOI.FindRequestHandlerDelegate <IRESTRequestHandler>();
                if (restRequestHandler == null)
                {
                    throw new RestErrorException("Service handler not found");
                }

                RestFilter restFilterOp = _restServiceSOI.GetFilter(opCode);

                if (null != restFilterOp && null != restFilterOp.PreFilter)
                {
                    restInput = restFilterOp.PreFilter(restInput);
                }

                byte[] response =
                    restRequestHandler.HandleRESTRequest(restInput.Capabilities, restInput.ResourceName, restInput.OperationName, restInput.OperationInput,
                                                         restInput.OutputFormat, restInput.RequestProperties, out responseProperties);

                if (null == restFilterOp || null == restFilterOp.PostFilter)
                {
                    return(response);
                }

                string newResponseProperties;
                var    newResponse = restFilterOp.PostFilter(restInput, response, responseProperties, out newResponseProperties);
                responseProperties = newResponseProperties;

                return(newResponse);
            }
            catch (RestErrorException restException)
            {
                // pre- or post- filters can throw restException with the error JSON output in the Message property.
                // we catch them here and return JSON response.
                responseProperties = "{\"Content-Type\":\"text/plain;charset=utf-8\"}";
                //catch and return a JSON error from the pre- or postFilter.
                return(System.Text.Encoding.UTF8.GetBytes(restException.Message));
            }
        }
        private RestHandlerOpCode GetHandlerOpCode(string resourceName, string operationName, bool isAskingForReturnUpdates = false)
        {
            if (isAskingForReturnUpdates)
            {
                return(CustomRESTHandlerOpCode.RootReturnUpdates);
            }


            RestHandlerOpCode opCode = RestSOIHelper.GetHandlerOpCode(resourceName, operationName);

            if (opCode != RestHandlerOpCode.DefaultNoOp)
            {
                return(opCode);
            }

            // The code below deals with the custom REST operation codes. This is required to enable REST request filtering for custom SOEs.
            // In this example the switch statement simply duplicates RestSOIHelper.GetHandlerOpCode() call.

            // If you don't plan to support filtering for any custom SOEs, remove code below until the end of the method.
            // If you want to support filtering for custom SOEs, modify the code below to match your needs.

            var    resName        = resourceName.TrimStart('/'); //remove leading '/' to prevent empty string at index 0
            var    resourceTokens = (resName ?? "").ToLower().Split('/');
            string opName         = (operationName ?? "").ToLower();

            switch (resourceTokens[0])
            {
            case "":
                switch (opName)
                {
                case "":
                    return(RestHandlerOpCode.Root);

                case "export":
                    return(RestHandlerOpCode.RootExport);

                case "find":
                    return(RestHandlerOpCode.RootFind);

                case "identify":
                    return(RestHandlerOpCode.RootIdentify);

                case "generatekml":
                    return(RestHandlerOpCode.RootGenerateKml);

                default:
                    return(RestHandlerOpCode.DefaultNoOp);
                }

            case "layers":
            {
                var tokenCount = resourceTokens.GetLength(0);
                if (1 == tokenCount)
                {
                    return(RestHandlerOpCode.RootLayers);
                }
                if (2 == tokenCount)
                {
                    switch (opName)
                    {
                    case "":
                        return(RestHandlerOpCode.LayerRoot);

                    case "query":
                        return(RestHandlerOpCode.LayerQuery);

                    case "queryRelatedRecords":
                        return(RestHandlerOpCode.LayerQueryRelatedRecords);

                    default:
                        return(RestHandlerOpCode.DefaultNoOp);
                    }
                }
            }
            break;

            case "legend":
                return(RestHandlerOpCode.RootLegend);

            case "dynamiclayer":
                switch (opName)
                {
                case "query":
                    return(RestHandlerOpCode.DefaultNoOp); //MyRESTHandlerOpCode.DynamicLayerQuery;

                default:
                    return(RestHandlerOpCode.DefaultNoOp);
                }

            default:
                return(RestHandlerOpCode.DefaultNoOp);
            }
            return(RestHandlerOpCode.DefaultNoOp);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="restFilterOp"></param>
        /// <param name="restInput"></param>
        /// <param name="authorizedLayers"></param>
        /// <param name="responseProperties"></param>
        /// <returns></returns>
        private byte[] FilterRESTRequest (
                                          RestHandlerOpCode opCode,
                                          RestRequestParameters restInput,
                                          out string responseProperties )
        {
            try
            {
                responseProperties = null;
                IRESTRequestHandler restRequestHandler = _restServiceSOI.FindRequestHandlerDelegate<IRESTRequestHandler>();
                if (restRequestHandler == null)
                    throw new RestErrorException("Service handler not found");

                RestFilter restFilterOp = _restServiceSOI.GetFilter(opCode);

                if (null != restFilterOp && null != restFilterOp.PreFilter)
                    restInput = restFilterOp.PreFilter(restInput);

                byte[] response =
                    restRequestHandler.HandleRESTRequest(restInput.Capabilities, restInput.ResourceName, restInput.OperationName, restInput.OperationInput,
                        restInput.OutputFormat, restInput.RequestProperties, out responseProperties);

                if (null == restFilterOp || null == restFilterOp.PostFilter)
                    return response;
                
                string newResponseProperties;
                var newResponse = restFilterOp.PostFilter(restInput, response, responseProperties, out newResponseProperties);
                responseProperties = newResponseProperties;

                return newResponse;
            }
            catch (RestErrorException restException)
            {
                // pre- or post- filters can throw restException with the error JSON output in the Message property.
                // we catch them here and return JSON response.
                responseProperties = "{\"Content-Type\":\"text/plain;charset=utf-8\"}";
                //catch and return a JSON error from the pre- or postFilter.
                return System.Text.Encoding.UTF8.GetBytes(restException.Message);
            }
        }