public override DataSet Clone()
        {
            Map_Features_DataSet cln = ((Map_Features_DataSet)(base.Clone()));

            cln.InitVars();
            return(cln);
        }
        /// <summary> Build the HTML for the feature index for this item </summary>
        /// <param name="html"> Stringbuilder to feed the HTML into </param>
        /// <param name="features"> Dataset containig all of the features linked to this item </param>
        protected internal void Create_Feature_Index( TextWriter Output, Map_Features_DataSet features)
        {
            if (features == null)
            {
                Output.WriteLine("<br />");
                Output.WriteLine("<center><b>UNABLE TO LOAD FEATURES FROM DATABASE</b></center>");
                Output.WriteLine("<br />");
                CurrentMode.Mode = Display_Mode_Enum.Contact;
                Output.WriteLine("<center>Click <a href=\"" + CurrentMode.Redirect_URL() + "\">here</a> to report this issue.</center>");
                Output.WriteLine("<br />");
                CurrentMode.Mode = Display_Mode_Enum.Item_Display;
                return;
            }

                string currentView = CurrentMode.ViewerCode;

                // This will be presented in a table, so start the table
                Output.WriteLine( "<table width=\"100%\">");

                // Determine (roughly) how many rows for each side
                // of the column
                int rows_per_column = features.Features.Count / 2;
                if (( features.Features.Count % 2 ) > 0 )
                    rows_per_column++;

                // Start the large table for each section
                Output.WriteLine("\t<tr>");
                Output.WriteLine("\t\t<td width=\"46%\" valign=\"top\">");

                // Create the first column of feature information
                Insert_One_Feature_Column( Output, features, 0, rows_per_column );

                // Move to second column of large table, after making a small margin column
                Output.WriteLine("\t\t</td>");
                Output.WriteLine("\t\t<td width=\"8%\"></td> <!-- Spacer Column -->");
                Output.WriteLine("\t\t<td width=\"46%\" valign=\"top\">");

                // Create the second column of feature information
                Insert_One_Feature_Column(Output, features, rows_per_column, features.Features.Count);

                // Finish off the large table
                Output.WriteLine("\t\t</td>\n\t</tr>\n</table>");
                Output.WriteLine("<!-- End output from GEMS_Map_Object.Feature_Index -->");

                CurrentMode.ViewerCode = currentView;
        }
        /// <summary> Gets the list of all map features linked to a particular item  </summary>
        /// <param name="ItemID"> ItemID for the item of interest</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <returns> List of all features linked to the item of interest </returns>
        /// <remarks> This calls the 'Auth_Get_All_Features_By_Item' stored procedure </remarks> 
        public static Map_Features_DataSet Get_All_Features_By_Item(int ItemID, Custom_Tracer Tracer)
        {
            try
            {
                // Create the connection
                SqlConnection connect = new SqlConnection( connectionString );

                // Create the command
                SqlCommand executeCommand = new SqlCommand("Auth_Get_All_Features_By_Item", connect)
                                                {CommandType = CommandType.StoredProcedure};
                executeCommand.Parameters.AddWithValue( "@itemid", ItemID );
                executeCommand.Parameters.AddWithValue( "@filter", 1 );

                // Create the adapter
                SqlDataAdapter adapter = new SqlDataAdapter( executeCommand );

                // Add appropriate table mappings
                adapter.TableMappings.Add("Table", "Features");
                adapter.TableMappings.Add("Table1", "Types");

                // Fill the strongly typed dataset
                Map_Features_DataSet features = new Map_Features_DataSet();
                adapter.Fill( features );

                // Return the fully built object
                return features;
            }
            catch (Exception ee)
            {
                lastException = ee;
                if (Tracer != null)
                {
                    Tracer.Add_Trace("SobekCM_Database.Get_All_Features_By_Item", "Exception caught during database work", Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("SobekCM_Database.Get_All_Features_By_Item", ee.Message, Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("SobekCM_Database.Get_All_Features_By_Item", ee.StackTrace, Custom_Trace_Type_Enum.Error);
                }
                return null;
            }
        }
        /// <summary> Insert the HTML for a single feature column into the Stringbuilder </summary>
        /// <param name="html"> Stringbuilder to feed the HTML into </param>
        /// <param name="features"> Dataset containig all of the features linked to this item </param>
        /// <param name="startRow"> Row of the set of features to begin on </param>
        /// <param name="endRow"> Last row in the set of features </param>
        protected internal void Insert_One_Feature_Column( TextWriter Output, Map_Features_DataSet features, int startRow, int endRow )
        {
            // Declare some variables for looping
            string lastFeatureName = "%";

            // Start the table for this row
            Output.WriteLine("\t\t\t<table width=\"100%\"> <!-- Table to display a single column of feature information -->");

            // Now, loop through all the results
            int i = startRow;
            while ( i < endRow )
            {
                // Get this feature
                Map_Features_DataSet.FeaturesRow thisFeature = features.Features[ i++ ];

                // Only display this if it is not null
                if ((thisFeature.IssorterNull()) || (thisFeature.sorter.Trim().Length <= 0)) continue;

                // If this feature name starts with a new letter, add the letter now
                if ( thisFeature.sorter.Trim()[0] != lastFeatureName[0] )
                {
                    // Add a row for the letter
                    Output.WriteLine("\t\t\t\t<tr> <td colspan=\"2\" class=\"bigletter\" align=\"center\">" + (thisFeature.sorter.Trim())[0] + "</td></tr>");
                    lastFeatureName = thisFeature.sorter.Trim();
                }

                // Start this row
                Output.WriteLine("\t\t\t\t<tr class=\"index\">");

                // Create the string to display
                string display;
                if (( !thisFeature.IsCorporateNameNull() ) && ( thisFeature.CorporateName.Length > 0 ))
                {
                    // Is there a building use for this as well
                    if (( !thisFeature.IsFeatureNameNull() ) && ( thisFeature.FeatureName.Trim().Length > 0 ))
                        display = thisFeature.CorporateName + ", " + thisFeature.FeatureName;
                    else
                        display = thisFeature.CorporateName;
                }
                else
                {
                    // Add location desc, if there is one
                    if (( !thisFeature.IsLocationDescNull() ) && ( thisFeature.LocationDesc.Length > 0 ))
                        display = thisFeature.FeatureName + " ( " + thisFeature.LocationDesc + " )";
                    else
                        display = thisFeature.FeatureName;
                }

                // Add the name
                Output.WriteLine("\t\t\t\t\t<td>" + display + "</td>");

                // Add the link to the sheet
                CurrentMode.ViewerCode = thisFeature["PageSequence"].ToString();
                Output.WriteLine("\t\t\t\t\t<td><a href=\"" + CurrentMode.Redirect_URL() + "\">" + thisFeature.PageName.Replace("Sheet", "").Trim() + "</a></td>");

                // End this row
                Output.WriteLine("\t\t\t\t</tr>");
            }

            // End this table
            Output.WriteLine("\t\t\t</table>");
        }