/// <summary>
        ///     Handles the incoming rest requests
        /// </summary>
        /// <param name="boundVariables"> The bound variables. </param>
        /// <param name="operationInput"> The operation input. </param>
        /// <param name="outputFormat"> The output format. </param>
        /// <param name="requestProperties"> The request properties. </param>
        /// <param name="responseProperties"> The response properties. </param>
        /// <returns> </returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static byte[] Handler(NameValueCollection boundVariables, JsonObject operationInput,
                                     string outputFormat, string requestProperties,
                                     out string responseProperties)
        {
            responseProperties = null;
            var errors = new ErrorContainer(400);
            var wkid = 26912;

            //pull out all the variables
            var featureClass = operationInput.GetStringValue("featureClass");
            var returnValues = operationInput.GetStringValue("returnValues");
            var predicate = operationInput.GetStringValue("predicate", nullable: true);
            var geometryJson = operationInput.GetStringValue("geometry", nullable: true);
            var wkidInput = operationInput.GetNumberValue("wkid", nullable: true);
            var bufferInput = operationInput.GetNumberValue("buffer", nullable: true);

            if (wkidInput > 0)
            {
                wkid = Convert.ToInt32(wkidInput);
            }

            var isSafeSqlCommand = new IsSafeSqlCommand(new[]
                {
                    featureClass, returnValues, predicate
                });

            if (!CommandExecutor.ExecuteCommand(isSafeSqlCommand))
            {
                errors.Add("Input appears to be unsafe. That is all I will tell you.");
            }

            GeometryContainer container = null;
            ISpatialReference newSpatialRefefence = null;
            ISpatialReferenceFactory srFactory = null;

            //reproject to our data's spatial reference
            if (wkid != 26912)
            {
                srFactory = new SpatialReferenceEnvironmentClass();

                var isProjected = true;
                try
                {
                    newSpatialRefefence = srFactory.CreateProjectedCoordinateSystem(wkid);
                }
                catch (ArgumentException)
                {
                    isProjected = false;
                }

                if (!isProjected)
                {
                    newSpatialRefefence = srFactory.CreateGeographicCoordinateSystem(wkid);
                }
            }

            //input has a geometry - deal with it
            if (!string.IsNullOrEmpty(geometryJson))
            {
                var extractGeometryCommand = new ExtractGeometryCommand(geometryJson);
                container = CommandExecutor.ExecuteCommand(extractGeometryCommand);

                if (container == null)
                {
                    var message = "Geometry coordinates appear to be invalid.";

                    if (!string.IsNullOrEmpty(extractGeometryCommand.ErrorMessage))
                    {
                        message += " Maybe this information can help: {0}".With(extractGeometryCommand.ErrorMessage);
                    }

                    errors.Add(message);
                }

                //input is in different projection - reproject it
                if (wkid != 26912)
                {
                    if (srFactory == null)
                    {
                        srFactory = new SpatialReferenceEnvironmentClass();
                    }

                    var toUtm = srFactory.CreateProjectedCoordinateSystem(26912);

                    if (container != null)
                    {
                        foreach (var points in container.Coordinates)
                        {
                            var point = new PointClass
                                {
                                    X = points[0],
                                    Y = points[1],
                                    SpatialReference = newSpatialRefefence
                                };

                            point.Project(toUtm);

                            if (point.IsEmpty)
                            {
                                errors.Add("Input geometry is empty. Check your x and y values.");
                                return Json(errors);
                            }

                            container.Geometry = point;

                            points[0] = point.X;
                            points[1] = point.Y;
                        }
                    }
                }

                //buffer point - set container type to polygon
                if (bufferInput > 0 && container != null)
                {
                    container.Geometry = CommandExecutor.ExecuteCommand(new BufferGeometryCommand(container, bufferInput));
                    container.Type = "POLYGON";
                }
            }

            var sdeConnector = SdeConnectorFactory.Create(featureClass);

            if (sdeConnector == null)
            {
                errors.Add("{0} was not found in our database. ".With(featureClass) +
                           "A valid example would be SGID10.BOUNDARIES.Counties.");
            }

            if (errors.HasErrors)
            {
                return Json(errors);
            }

// ReSharper disable PossibleNullReferenceException because of returning errors if null
            var workspace = sdeConnector.Connect();
// ReSharper restore PossibleNullReferenceException

            var featureWorkspace = workspace as IFeatureWorkspace;

            if (featureWorkspace == null)
            {
                errors.Add("Error connecting to SDE.");
                return Json(errors);
            }

            var values = returnValues.Split(',').Select(x => x.Trim()).ToArray();

            var commandToExecute = SpatialCommandFactory.Get(container, featureWorkspace, featureClass, values,
                                                             predicate, newSpatialRefefence);

            var result = CommandExecutor.ExecuteCommand(commandToExecute);

            if (!string.IsNullOrEmpty(commandToExecute.ErrorMessage))
            {
                errors.Add(commandToExecute.ErrorMessage);
                return Json(errors);
            }

            return Json(result);
        }
        /// <summary>
        ///     Handles the incoming rest requests
        /// </summary>
        /// <param name="boundVariables"> The bound variables. </param>
        /// <param name="operationInput"> The operation input. </param>
        /// <param name="outputFormat"> The output format. </param>
        /// <param name="requestProperties"> The request properties. </param>
        /// <param name="responseProperties"> The response properties. </param>
        /// <returns> </returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static byte[] Handler(NameValueCollection boundVariables, JsonObject operationInput,
                                     string outputFormat, string requestProperties,
                                     out string responseProperties)
        {
            responseProperties = null;
            var errors = new ErrorContainer(400);
            var wkid = 26912;
            const string featureClass = "SGID10.TRANSPORTATION.UDOTRoutes_LRS";

            //pull out all the variables
            var x = operationInput.GetNumberValue("x");
            var y = operationInput.GetNumberValue("y");
            var wkidInput = operationInput.GetNumberValue("wkid", nullable: true);
            var bufferInput = operationInput.GetNumberValue("buffer", nullable: true);
            var includeRamps = operationInput.GetNumberValue("includeRamps", nullable: true);

            ISpatialReference newSpatialRefefence = null;
            ISpatialReferenceFactory srFactory = new SpatialReferenceEnvironment();

            if (wkidInput > 0)
            {
                wkid = Convert.ToInt32(wkidInput);
            }

            if (bufferInput < 1 || bufferInput > 200)
            {
                bufferInput = 100;
            }

            //reproject to our data's spatial reference
            if (wkid != 26912)
            {
                var isProjected = true;
                try
                {
                    newSpatialRefefence = srFactory.CreateProjectedCoordinateSystem(wkid);
                }
                catch (ArgumentException)
                {
                    isProjected = false;
                }

                if (!isProjected)
                {
                    newSpatialRefefence = srFactory.CreateGeographicCoordinateSystem(wkid);
                }
            }

            var utm = srFactory.CreateProjectedCoordinateSystem(26912);

            IPoint point = new Point
                {
                    X = x,
                    Y = y,
                    SpatialReference = utm
                };

            //input is in different projection - reproject it
            if (wkid != 26912)
            {
                point = new Point
                    {
                        X = x,
                        Y = y,
                        SpatialReference = newSpatialRefefence
                    };

                point.Project(utm);
            }

            var bufferGeometry = CommandExecutor.ExecuteCommand(
                new BufferGeometryCommand(new GeometryContainer
                    {
                        Geometry = point
                    }, bufferInput));

            var sdeConnector = SdeConnectorFactory.Create(featureClass);

            if (sdeConnector == null)
            {
                errors.Add("{0} was not found in our database. ".With(featureClass) +
                           "A valid example would be SGID10.BOUNDARIES.Counties.");
            }

            if (errors.HasErrors)
            {
                return Json(errors);
            }

// ReSharper disable PossibleNullReferenceException because of returning errors if null
            var workspace = sdeConnector.Connect();
// ReSharper restore PossibleNullReferenceException

            var featureWorkspace = workspace as IFeatureWorkspace;

            if (featureWorkspace == null)
            {
                errors.Add("Error connecting to SDE.");
                return Json(errors);
            }

            var whereClause = "(LABEL LIKE '0%') AND RT_DIR <> 'B'"; //gets rid of ramps, collectors, and federal aid routes
            if (includeRamps < 1)
            {
                whereClause = whereClause.Insert(0, "LEN(LABEL) = 5 AND ");
            }

            var spatFilter = new SpatialFilterClass
                {
                    SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects,
                    Geometry = bufferGeometry,
                    WhereClause = whereClause
                };

            var lrsFeatureClass = featureWorkspace.OpenFeatureClass(featureClass.Trim());
            var fCursor = lrsFeatureClass.Search(spatFilter, true);
            var candidates = new TopAndEqualMilepostCandidates(new ClosestMilepostComparer());

            IFeature row;
            while ((row = fCursor.NextFeature()) != null)
            {
                var shape = row.ShapeCopy as IPolyline;
                if (shape == null)
                {
                    continue;
                }

                IPoint hitPoint = new Point();
                var hitDistance = -1d;
                var hitPartIndex = -1;
                var hitSegmentIndex = -1;
                var increasingSide = false;

                var hitTest = shape as IHitTest;
                if (hitTest == null)
                {
                    continue;
                }

                var isHit = hitTest.HitTest(point, bufferInput, esriGeometryHitPartType.esriGeometryPartBoundary, hitPoint,
                                ref hitDistance, ref hitPartIndex, ref hitSegmentIndex, ref increasingSide);

                if (!isHit)
                {
                    continue;
                }

                var milepost = hitPoint.M;

                var distance = GetDistanceBetween(point, hitPoint);

                var routeName = CommandExecutor.ExecuteCommand(new GetValueForFieldCommand("LABEL", row.Fields, row));

                candidates.Add(new ClosestMilepost(milepost, routeName.ToString(), distance, increasingSide));

                Marshal.ReleaseComObject(row);
                Marshal.ReleaseComObject(shape);
                Marshal.ReleaseComObject(hitPoint);
            }

            Marshal.ReleaseComObject(lrsFeatureClass);
            Marshal.ReleaseComObject(workspace);
            Marshal.ReleaseComObject(spatFilter);

            return Json(candidates);
        }