private byte[] PostFilterRESTRoot(RestRequestParameters restInput, byte[] responseBytes, string responseProperties, out string newResponseProperties)
        {
            newResponseProperties = responseProperties;

            string originalResponse = System.Text.Encoding.UTF8.GetString(responseBytes);
            JavaScriptSerializer sr = new JavaScriptSerializer()
            {
                MaxJsonLength = int.MaxValue
            };
            var jsonResObj = sr.DeserializeObject(originalResponse) as IDictionary <string, object>;

            var contentsJO = jsonResObj["contents"] as IDictionary <string, object>;

            //modifying light version of 'Layers' resources
            var layersJA = contentsJO["layers"] as object[];
            //var jsLightLayer = layersJA[0] as IDictionary<string, object>;
            var jsLightLayer = layersJA.FirstOrDefault(j =>
            {
                var d = j as Dictionary <string, object>;
                return(_queryableLayerID.Equals(d["id"].ToString()));
            }) as IDictionary <string, object>;

            jsLightLayer["minScale"] = 0;
            jsLightLayer["maxScale"] = 0;
            contentsJO["layers"]     = new object[] { jsLightLayer }; //only returning the very first layer

            //modifying All Layer Resources
            var allResourcesJA = jsonResObj["resources"] as object[];
            var layersRJO      = allResourcesJA.FirstOrDefault(e =>
            {
                var jo = e as IDictionary <string, object>;
                if (!jo.ContainsKey("name"))
                {
                    return(false);
                }
                var name = jo["name"].ToString();
                return("layers" == name);
            }) as IDictionary <string, object>;

            var layerResourceJA = layersRJO["resources"] as object[];
            //we need to return only the first layer and remove visibility scale range from there.
            //var jsDetailLayer = layerResourceJA[0] as IDictionary<string, object>;

            //returning only the layer with detail streams i.e. the layerId = _querableLayerID
            var jsDetailLayer = layerResourceJA.FirstOrDefault(j =>
            {
                var d         = j as Dictionary <string, object>;
                var jsContent = d["contents"] as IDictionary <string, object>;
                return(_queryableLayerID.Equals(jsContent["id"].ToString(), StringComparison.CurrentCultureIgnoreCase));
            }) as IDictionary <string, object>;

            var jsDetailLyrContent = jsDetailLayer["contents"] as IDictionary <string, object>;

            jsDetailLyrContent["minScale"] = 0;
            jsDetailLyrContent["maxScale"] = 0;
            layersRJO["resources"]         = new object[] { jsDetailLayer };

            //updating the queryableLayer's and root's timeExtent with the timeExtent from the very first layer
            //this is due to a bug in map server that makes the service to take really long time to compute a layer (when 1:M joined to a pretty large table) time's extent
            var jsDetailLayer0      = layerResourceJA[0] as IDictionary <string, object>;              //the first layer
            var jsDetailLyrContent0 = jsDetailLayer0["contents"] as IDictionary <string, object>;
            var jsTimeInfoLyr0      = jsDetailLyrContent0["timeInfo"] as IDictionary <string, object>; //the timeInfor from the very first layer
            //var jsTimeExtentLyr0 = jsTimeInfoLyr0["timeExtent"] as object[];
            var jsDetailLyrTimeInfo = jsDetailLyrContent["timeInfo"] as IDictionary <string, object>;

            jsDetailLyrTimeInfo["timeExtent"] = jsTimeInfoLyr0["timeExtent"];
            //var jsDetailLyrTimeExtent = jsDetailLyrTimeInfo["timeExtent"] as object[];
            //jsDetailLyrTimeExtent[0] = jsTimeExtentLyr0[0];
            //jsDetailLyrTimeExtent[1] = jsTimeExtentLyr0[1];
            //update time extent for the root resources
            var jsTimeInfoRoot = contentsJO["timeInfo"] as IDictionary <string, object>;

            jsTimeInfoRoot["timeExtent"] = jsTimeInfoLyr0["timeExtent"];
            _defaultTimeInterval         = (int)jsTimeInfoRoot["defaultTimeInterval"];
            _defaultTimeIntervalUnits    = (esriTimeUnits)Enum.Parse(typeof(esriTimeUnits), (string)jsTimeInfoRoot["defaultTimeIntervalUnits"]);

            //var jsTimeExtentRoot = jsTimeInfoRoot["timeExtent"] as object[];
            //jsTimeExtentRoot[0] = jsTimeExtentLyr0[0];
            //jsTimeExtentRoot[1] = jsTimeExtentLyr0[1];

            //modifying legends
            var legendRJO = allResourcesJA.FirstOrDefault(e =>
            {
                var jo = e as IDictionary <string, object>;
                if (!jo.ContainsKey("name"))
                {
                    return(false);
                }
                var name = jo["name"].ToString();
                return("legend" == name);
            }) as IDictionary <string, object>;
            var jsLegendLyrContent = legendRJO["contents"] as IDictionary <string, object>;
            var jsLgdLayers        = jsLegendLyrContent["layers"] as object[];
            //var jsLgdLyr = jsLgdLayers[0] as IDictionary<string, object>;
            var jsLgdLyr = jsLgdLayers.FirstOrDefault(j =>
            {
                var d = j as Dictionary <string, object>;
                return(_queryableLayerID.Equals(d["layerId"].ToString(), StringComparison.CurrentCultureIgnoreCase));
            }) as IDictionary <string, object>;

            jsLgdLyr["minScale"] = 0;
            jsLgdLyr["maxScale"] = 0;
            if (_customLegend != null)
            {
                jsLgdLyr["legend"] = _customLegend; //GetCustomLegend();
            }
            jsLegendLyrContent["layers"] = new object[] { jsLgdLyr };

            return(System.Text.Encoding.UTF8.GetBytes(sr.Serialize(jsonResObj)));
        }
        protected override void OnClick()
        {
            IMxDocument pMxDoc = ArcMap.Document;

            if (pMxDoc.SelectedLayer == null)
            {
                MessageBox.Show("There is no layer selected.  First select a time-aware layer.");
                return;
            }

            IFeatureLayer pFLyr     = pMxDoc.SelectedLayer as IFeatureLayer;
            ITimeData     pTimeData = pFLyr as ITimeData;

            if (!pTimeData.SupportsTime)
            {
                MessageBox.Show("Select a time-aware layer first.");
                return;
            }
            m_myLayerTimeExtent = pTimeData.GetFullTimeExtent();

            ITimeDataDisplay pTimeDataDisplayProperties = pFLyr as ITimeDataDisplay;
            esriTimeUnits    LayerIntervalUnits         = pTimeDataDisplayProperties.TimeIntervalUnits;
            double           LayerInterval = pTimeDataDisplayProperties.TimeInterval;
            ITime            startTime     = m_myLayerTimeExtent.StartTime;
            ITime            endTime       = (ITime)((IClone)startTime).Clone();

            switch (LayerIntervalUnits)
            {
            case esriTimeUnits.esriTimeUnitsYears:
                ((ITimeOffsetOperator)endTime).AddYears(LayerInterval, false, true);
                break;

            case esriTimeUnits.esriTimeUnitsMonths:
                ((ITimeOffsetOperator)endTime).AddMonths(LayerInterval, false, true);
                break;

            case esriTimeUnits.esriTimeUnitsDays:
                ((ITimeOffsetOperator)endTime).AddDays(LayerInterval);
                break;

            case esriTimeUnits.esriTimeUnitsHours:
                ((ITimeOffsetOperator)endTime).AddHours(LayerInterval);
                break;

            case esriTimeUnits.esriTimeUnitsMinutes:
                ((ITimeOffsetOperator)endTime).AddMinutes(LayerInterval);
                break;

            case esriTimeUnits.esriTimeUnitsSeconds:
                ((ITimeOffsetOperator)endTime).AddSeconds(LayerInterval);
                break;
            }

            ITimeExtent pTimeExt = new TimeExtentClass();

            pTimeExt.SetExtent(startTime, endTime);
            m_layerInterval = pTimeExt.QueryTimeDuration();


            m_sliderDlg = new TimeSliderDialog(this);
            m_sliderDlg.Show();
        }