/// <summary>
        /// Inspects the properties of the features.
        /// </summary>
        /// <param name="objects"></param>
        /// <param name="Editor"></param>
        public void Inspect(ESRI.ArcGIS.Editor.IEnumRow objects, ESRI.ArcGIS.Editor.IEditor Editor)
        {
            try
            {
                SetParent(m_inspector.HWND, stabHwnd);
                SetParent(stabHwnd, picHwnd);

                ShowWindow(m_inspector.HWND, SW_SHOW);
                m_inspector.Inspect(objects, Editor);

                IEnumRow enumRow     = objects;
                IRow     row         = enumRow.Next();
                IFeature inspFeature = (IFeature)row;

                //user selected the layer name instead of a feature.
                if (objects.Count > 1)
                {
                    return;
                }

                switch (inspFeature.Shape.GeometryType)
                {
                case esriGeometryType.esriGeometryPolygon:
                {
                    //do this for polygons.
                    customListBox.Items.Clear();
                    ReportPolygons(inspFeature);
                    break;
                }

                case esriGeometryType.esriGeometryPolyline:
                {
                    //do this for lines.
                    customListBox.Items.Clear();
                    ReportPolylines(inspFeature);
                    break;
                }

                case esriGeometryType.esriGeometryPoint:
                {
                    //do this for points.
                    customListBox.Items.Clear();
                    ReportPoints(inspFeature);
                    break;
                }

                default:
                    break;
                } //End switch.
            }
            catch (Exception ex)
            {
                MessageBox.Show("IObjectInspector_Inspect: " + ex.Message);
            }
        }
        public void prepareGrid4Features(IEnumRow currentFeatures)
        {
            if (m_inspector == null)
            {
                //this is the default inspector shipped with the editor
                m_inspector = new FeatureInspector();

                SetParent(dataGridView1.Handle.ToInt32(), this.Handle.ToInt32());
            }


            DataGridView featureGridView = this.dataGridView1;

            // reset the feature grid
            featureGridView.Rows.Clear();


            if (currentFeatures == null)
            {
                return;
            }

            currentFeatures.Reset();

            IFeature currentFeature = currentFeatures.Next() as IFeature;

            Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tagkey> potentialTags = new Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tagkey>();


            // determine a unique collection of proposed and existing tags
            List<string> uniqueListofTags = new List<string>();
            Dictionary<string, string> commonTags = new Dictionary<string, string>();
            Geometry.esriGeometryType currentGeometryType = esriGeometryType.esriGeometryNull;
            IEnumerable<ESRI.ArcGIS.OSM.OSMClassExtension.tag> sameTags = null;

            while (currentFeature != null)
            {
                int osmTagsFieldIndex = currentFeature.Fields.FindField("osmTags");
                currentGeometryType = currentFeature.Shape.GeometryType;

                if (osmTagsFieldIndex != -1)
                {
                    ESRI.ArcGIS.OSM.OSMClassExtension.tag[] tagsOnCurrentFeature = _osmUtility.retrieveOSMTags((IRow)currentFeature, osmTagsFieldIndex, m_editor.EditWorkspace);

                    if (sameTags == null && tagsOnCurrentFeature != null)
                    {
                        sameTags = tagsOnCurrentFeature.ToArray<ESRI.ArcGIS.OSM.OSMClassExtension.tag>();
                    }
                    else if (sameTags != null && tagsOnCurrentFeature != null)
                    {
                        IEnumerable<ESRI.ArcGIS.OSM.OSMClassExtension.tag> both = tagsOnCurrentFeature.Intersect(sameTags, new ESRI.ArcGIS.OSM.OSMClassExtension.TagKeyComparer());
                        sameTags = both.ToArray<ESRI.ArcGIS.OSM.OSMClassExtension.tag>();
                    }

                    if (tagsOnCurrentFeature != null)
                    {
                        for (int index = 0; index < tagsOnCurrentFeature.Length; index++)
                        {
                            if (uniqueListofTags.Contains(tagsOnCurrentFeature[index].k) == false)
                            {
                                uniqueListofTags.Add(tagsOnCurrentFeature[index].k);
                            }

                            // check if the tag key already exists
                            if (commonTags.ContainsKey(tagsOnCurrentFeature[index].k) == true)
                            {
                                if (commonTags[tagsOnCurrentFeature[index].k] == tagsOnCurrentFeature[index].v)
                                {
                                    // the tag values still match - don't do anything
                                }
                                else
                                {
                                    // the values are different - purge the existing value
                                    commonTags[tagsOnCurrentFeature[index].k] = String.Empty;
                                }
                            }
                            else
                            {
                                // the tag doesn't exist yet in the overall collection, 
                                // add the first entry
                                commonTags.Add(tagsOnCurrentFeature[index].k, tagsOnCurrentFeature[index].v);
                            }
                        }
                    }
                }

                // determine potential tag candidates based on the osmfeature schema
                string featureString = String.Empty;

                //let's get the first domain entry and use it as the main feature theme

                for (int fieldIndex = 0; fieldIndex < currentFeature.Fields.FieldCount; fieldIndex++)
                {
                    if (String.IsNullOrEmpty(featureString))
                    {
                        if (currentFeature.Fields.get_Field(fieldIndex).Type == esriFieldType.esriFieldTypeString)
                        {
                            System.Object attributeValue = currentFeature.get_Value(fieldIndex);

                            if (attributeValue != System.DBNull.Value)
                            {
                                foreach (string lookingforDomain in m_domainDictionary.Keys)
                                {
                                    if (currentFeature.Fields.get_Field(fieldIndex).Name == lookingforDomain)
                                    {
                                        featureString = lookingforDomain + "=" + attributeValue.ToString();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                ESRI.ArcGIS.OSM.OSMClassExtension.osmfeature OSMInspectorFeatureType = null;

                if (m_editFeatures.Keys.Contains(featureString))
                {
                    OSMInspectorFeatureType = m_editFeatures[featureString];
                }

                if (OSMInspectorFeatureType != null)
                {
                    if (OSMInspectorFeatureType.tag != null)
                    {
                        for (int index = 0; index < OSMInspectorFeatureType.tag.Length; index++)
                        {
                            if (commonTags.ContainsKey(OSMInspectorFeatureType.tag[index].@ref) == false)
                            {
                                commonTags.Add(OSMInspectorFeatureType.tag[index].@ref, String.Empty);
                            }
                        }
                    }
                }

                currentFeature = currentFeatures.Next() as IFeature;
            }


            // get a listing of all possible tags
            Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tagkey> localTags = new Dictionary<string, ESRI.ArcGIS.OSM.OSMClassExtension.tagkey>();

            foreach (ESRI.ArcGIS.OSM.OSMClassExtension.tagkey tagKeyItem in m_editTags.Values)
            {
                localTags.Add(tagKeyItem.name, tagKeyItem);
            }


            // now let's go through our unique list of proposed and existing tags
            // and fill the grid accordingly

            DataGridViewRow currentRow = null;

            foreach (KeyValuePair<string, string> osmTagValuePair in commonTags)
            {
                currentRow = new DataGridViewRow();

                // name of the tag - tag type
                DataGridViewCell currentTagCell = new DataGridViewTextBoxCell();
                currentTagCell.Value = osmTagValuePair.Key;

                // for localization include the translated language into a tooltip
                if (m_editTags.ContainsKey(osmTagValuePair.Key))
                {
                    if (!String.IsNullOrEmpty(m_editTags[osmTagValuePair.Key].displayname))
                    {
                        currentTagCell.ToolTipText = m_editTags[osmTagValuePair.Key].displayname;
                    }
                }


                currentRow.Cells.Insert(0, currentTagCell);

                // the default case is not to allow the user change the key field
                bool canEdit = false;

                if (m_editTags.ContainsKey(osmTagValuePair.Key))
                {
                    if (m_editTags[osmTagValuePair.Key].editableSpecified)
                    {
                        canEdit = m_editTags[osmTagValuePair.Key].editable;
                    }
                }

                currentRow.Cells[0].ReadOnly = !canEdit;

                // value of the tag
                // depending on the tag type we'll need to create a different cell type
                DataGridViewCell currentValueCell = null;

                if (m_editTags.ContainsKey(osmTagValuePair.Key))
                {
                    switch (m_editTags[osmTagValuePair.Key].tagtype)
                    {
                        case ESRI.ArcGIS.OSM.OSMClassExtension.tagkeyTagtype.tag_list:
                            currentValueCell = new DataGridViewComboBoxCell();
                            try
                            {
                                foreach (ESRI.ArcGIS.OSM.OSMClassExtension.tagvalue value in m_editTags[osmTagValuePair.Key].tagvalue)
                                {
                                    ((DataGridViewComboBoxCell)currentValueCell).Items.Add(value.name);
                                }
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine(ex.Message);
                            }
                            break;
                        case ESRI.ArcGIS.OSM.OSMClassExtension.tagkeyTagtype.tag_integer:
                            currentValueCell = new DataGridViewTextBoxCell();
                            break;
                        case ESRI.ArcGIS.OSM.OSMClassExtension.tagkeyTagtype.tag_double:
                            currentValueCell = new DataGridViewTextBoxCell();
                            break;
                        case ESRI.ArcGIS.OSM.OSMClassExtension.tagkeyTagtype.tag_string:
                            currentValueCell = new DataGridViewTextBoxCell();
                            break;
                        default:
                            currentValueCell = new DataGridViewTextBoxCell();
                            break;
                    }
                }
                else if (m_domainDictionary.ContainsKey(osmTagValuePair.Key))
                {
                    currentValueCell = new DataGridViewComboBoxCell();
                    ESRI.ArcGIS.OSM.OSMClassExtension.domain currentDomain = null;

                    switch (currentGeometryType)
                    {
                        case esriGeometryType.esriGeometryAny:
                            break;
                        case esriGeometryType.esriGeometryBag:
                            break;
                        case esriGeometryType.esriGeometryBezier3Curve:
                            break;
                        case esriGeometryType.esriGeometryCircularArc:
                            break;
                        case esriGeometryType.esriGeometryEllipticArc:
                            break;
                        case esriGeometryType.esriGeometryEnvelope:
                            break;
                        case esriGeometryType.esriGeometryLine:
                            break;
                        case esriGeometryType.esriGeometryMultiPatch:
                            break;
                        case esriGeometryType.esriGeometryMultipoint:
                            break;
                        case esriGeometryType.esriGeometryNull:
                            break;
                        case esriGeometryType.esriGeometryPath:
                            break;
                        case esriGeometryType.esriGeometryPoint:
                            currentDomain = m_domainDictionary[osmTagValuePair.Key];

                            foreach (ESRI.ArcGIS.OSM.OSMClassExtension.domainvalue item in currentDomain.domainvalue)
                            {
                                for (int geometryIndex = 0; geometryIndex < item.geometrytype.Length; geometryIndex++)
                                {
                                    if (item.geometrytype[geometryIndex] == ESRI.ArcGIS.OSM.OSMClassExtension.geometrytype.point)
                                    {
                                        try
                                        {
                                            ((DataGridViewComboBoxCell)currentValueCell).Items.Add(item.value);
                                        }
                                        catch (Exception ex)
                                        {
                                            System.Diagnostics.Debug.WriteLine(ex.Message);
                                        }
                                    }
                                }
                            }
                            break;
                        case esriGeometryType.esriGeometryPolygon:
                            currentDomain = m_domainDictionary[osmTagValuePair.Key];

                            foreach (ESRI.ArcGIS.OSM.OSMClassExtension.domainvalue item in currentDomain.domainvalue)
                            {
                                for (int geometryIndex = 0; geometryIndex < item.geometrytype.Length; geometryIndex++)
                                {
                                    if (item.geometrytype[geometryIndex] == ESRI.ArcGIS.OSM.OSMClassExtension.geometrytype.polygon)
                                    {
                                        try
                                        {
                                            ((DataGridViewComboBoxCell)currentValueCell).Items.Add(item.value);
                                        }
                                        catch (Exception ex)
                                        {
                                            System.Diagnostics.Debug.WriteLine(ex.Message);
                                        }
                                    }
                                }
                            }
                            break;
                        case esriGeometryType.esriGeometryPolyline:
                            currentDomain = m_domainDictionary[osmTagValuePair.Key];

                            foreach (ESRI.ArcGIS.OSM.OSMClassExtension.domainvalue item in currentDomain.domainvalue)
                            {
                                for (int geometryIndex = 0; geometryIndex < item.geometrytype.Length; geometryIndex++)
                                {
                                    if (item.geometrytype[geometryIndex] == ESRI.ArcGIS.OSM.OSMClassExtension.geometrytype.line)
                                    {
                                        try
                                        {
                                            ((DataGridViewComboBoxCell)currentValueCell).Items.Add(item.value);
                                        }
                                        catch (Exception ex)
                                        {
                                            System.Diagnostics.Debug.WriteLine(ex.Message);
                                        }
                                    }
                                }
                            }
                            break;
                        case esriGeometryType.esriGeometryRay:
                            break;
                        case esriGeometryType.esriGeometryRing:
                            break;
                        case esriGeometryType.esriGeometrySphere:
                            break;
                        case esriGeometryType.esriGeometryTriangleFan:
                            break;
                        case esriGeometryType.esriGeometryTriangleStrip:
                            break;
                        case esriGeometryType.esriGeometryTriangles:
                            break;
                        default:
                            break;
                    }
                }
                else
                { // unkown keys are treated as strings
                    currentValueCell = new DataGridViewTextBoxCell();
                }

                // add the value only we have a value and if the tag is common among all features
                if (String.IsNullOrEmpty(osmTagValuePair.Value) == false)
                {
                    ESRI.ArcGIS.OSM.OSMClassExtension.tag compareTag = new ESRI.ArcGIS.OSM.OSMClassExtension.tag();
                    compareTag.k = osmTagValuePair.Key;

                    if (sameTags.Contains(compareTag, new ESRI.ArcGIS.OSM.OSMClassExtension.TagKeyComparer()))
                    {
                        currentValueCell.Value = osmTagValuePair.Value;
                    }
                }

                // for localization include the translated language into a tooltip
                if (m_editTags.ContainsKey((string)currentTagCell.Value))
                {
                    if (!String.IsNullOrEmpty((string)currentValueCell.Value))
                    {
                        ESRI.ArcGIS.OSM.OSMClassExtension.tagvalue[] possibleValues = m_editTags[(string)currentTagCell.Value].tagvalue;

                        if (possibleValues != null)
                        {
                            for (int valueIndex = 0; valueIndex < possibleValues.Length; valueIndex++)
                            {
                                if (currentValueCell.Value.Equals(possibleValues[valueIndex].name) == true)
                                {
                                    if (!String.IsNullOrEmpty(possibleValues[valueIndex].displayname))
                                    {
                                        currentValueCell.ToolTipText = possibleValues[valueIndex].displayname;
                                    }
                                }
                            }
                        }
                    }
                }

                currentRow.Cells.Insert(1, currentValueCell);

                // the assumption here is that values are usually open to user edits
                canEdit = true;
                currentRow.Cells[1].ReadOnly = !canEdit;

                DataGridViewLinkCell currentInfoCell = new DataGridViewLinkCell();
                currentInfoCell.LinkBehavior = LinkBehavior.SystemDefault;

                if (m_editTags.ContainsKey(osmTagValuePair.Key))
                {
                    if (String.IsNullOrEmpty(m_editTags[osmTagValuePair.Key].infoURL))
                    {
                        currentInfoCell.Value = new Uri(m_baseInfoURI + HttpUtility.UrlEncode("Key:" + osmTagValuePair.Key));
                    }
                    else
                    {
                        currentInfoCell.Value = new Uri(m_editTags[osmTagValuePair.Key].infoURL);
                    }
                    currentRow.Cells.Insert(2, currentInfoCell);
                }
                else
                {
                    currentInfoCell.Value = new Uri(m_baseInfoURI + HttpUtility.UrlEncode("Key:" + osmTagValuePair.Key));
                }

                featureGridView.Rows.Add(currentRow);

                if (localTags.ContainsKey(osmTagValuePair.Key))
                {
                    localTags.Remove(osmTagValuePair.Key);
                }
            }

            // add the list in the first column of the last row
            DataGridViewRow lastRow = new DataGridViewRow();
            DataGridViewComboBoxCell currentKeyCell = new DataGridViewComboBoxCell();
            try
            {
                // show a sorted list of tags to the user
                IEnumerable<string> sortedKeys = localTags.Keys.OrderBy(myKey => myKey);

                foreach (string currentKey in sortedKeys)
                {
                    currentKeyCell.Items.Add(currentKey);
                }
            }
            catch { }

            lastRow.Cells.Insert(0, currentKeyCell);

            featureGridView.Rows.Add(lastRow);

        }
        void IObjectInspector.Inspect(IEnumRow objects, IEditor Editor)
        {
            try
            {
                if (m_inspector == null)
                {
                    m_inspector = new FeatureInspectorClass();
                }

                //SetParent(m_inspector.HWND, this.Handle.ToInt32());
                ShowWindow(m_inspector.HWND, SW_SHOW);

                m_inspector.Inspect(objects, Editor);

                if (Editor == null)
                {
                    return;
                }

                if (objects == null)
                {
                    return;
                }

                if (IsInitialized == false)
                    Init(Editor);

                m_editor = Editor;
                m_enumRow = objects;

                IEnumFeature enumFeatures = Editor.EditSelection;
                enumFeatures.Reset();

                int featureCount = 0;

                while (enumFeatures.Next() != null)
                {
                    featureCount = featureCount + 1;
                }

                IEnumRow enumRow = objects;
                enumRow.Reset();
                IRow row = enumRow.Next();

                IFeature inspFeature = (IFeature)row;

                //user selected the layer name instead of a feature.
                if (objects.Count > 1)
                {
                    prepareGrid4Features(objects);
                }
                else
                {
                    prepareGrid4Feature(inspFeature);
                }

                currentlyEditedRows = enumRow;
            }
            catch (Exception ex)
            {
                ClearGrid();

                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
        public void Inspect(ESRI.ArcGIS.Editor.IEnumRow objects, ESRI.ArcGIS.Editor.IEditor Editor)
        {
            try
            {
                if (m_osmFeatureInspector == null)
                {
                    m_osmFeatureInspector = new OSMFeatureInspectorUI();
                }

                if (m_inspector == null)
                {
                    m_inspector = new FeatureInspectorClass();
                }

                ShowWindow(m_inspector.HWND, SW_SHOW);
                m_inspector.Inspect(objects, Editor);

                if (Editor == null)
                {
                    return;
                }

                if (objects == null)
                {
                    return;
                }

                if (m_osmFeatureInspector.IsInitialized == false)
                {
                    m_osmFeatureInspector.Init(Editor);
                }

                m_editor  = Editor;
                m_enumRow = objects;

                IEnumFeature enumFeatures = Editor.EditSelection;
                enumFeatures.Reset();

                int featureCount = 0;

                while (enumFeatures.Next() != null)
                {
                    featureCount = featureCount + 1;
                }

                IEnumRow enumRow = objects;
                enumRow.Reset();
                IRow row = enumRow.Next();

                IFeature inspFeature = (IFeature)row;

                //user selected the layer name instead of a feature.
                if (objects.Count > 1)
                {
                    m_osmFeatureInspector.prepareGrid4Features(objects);
                }
                else
                {
                    m_osmFeatureInspector.prepareGrid4Feature(inspFeature);
                }

                m_osmFeatureInspector.currentlyEditedRows = enumRow;
            }
            catch (Exception ex)
            {
                if (m_osmFeatureInspector != null)
                {
                    m_osmFeatureInspector.ClearGrid();
                }

                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }