/// <summary>
        /// Retrieves the selected metadata (in search result listbox) from CSW catalog. Exception shall be thrown.
        /// </summary>
        /// <remarks>
        /// Called in View Metadata, Download Metadata, and Add to Map
        /// </remarks>
        /// <returns>A XMLDocument object if metadata was retrieved successfully. Null if otherwise.</returns>
        private void RetrieveAddToMapInfoFromCatalog()
        {
            try
            {
                // validate
                if (cmbCswCatalog.SelectedIndex == -1)
                {
                    MessageBox.Show(resourceManager.GetString("catalogNotSelected"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (lstSearchResults.SelectedIndex == -1) { throw new Exception(resourceManager.GetString("searchNotSelected")); }
                CswCatalog catalog = (CswCatalog)cmbCswCatalog.SelectedItem;
                if (catalog == null) { throw new NullReferenceException(resourceManager.GetString("catalogNotSpecified")); }
                CswRecord record = (CswRecord)lstSearchResults.SelectedItem;
                if (record == null) throw new NullReferenceException(resourceManager.GetString("searchNotSelected"));

                // connect to catalog if needed
                if (!catalog.IsConnected())
                {
                    string errMsg = "";
                    try { catalog.Connect(); }
                    catch (Exception ex) { errMsg = ex.Message; }

                    // exit if still not connected
                    if (!catalog.IsConnected())
                    {
                        MessageBox.Show(resourceManager.GetString("catalogConnectFailed"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

                CswSearchRequest searchRequest = new CswSearchRequest();
                searchRequest.Catalog = catalog;
                try
                {
                    searchRequest.GetAddToMapInfoByID(record.ID);
                    _mapServerUrl = searchRequest.GetMapServerUrl();

                }
                catch (Exception ex)
                {
                    FormMessageBox frmMessageBox = new FormMessageBox();
                    frmMessageBox.Init("Failed to retrieve metadata from service: " + ex.Message,
                                        "Response from CSW service:\r\n" + searchRequest.GetResponse().ResponseXML,
                                        "Error");
                    frmMessageBox.ShowDialog(this);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(resourceManager.GetString("loadXMLException"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }
        /// <summary>
        /// Retrieves the selected metadata (in search result listbox) from CSW catalog. 
        /// It handles including GUI validation and metadata retrieveal. 
        /// </summary>
        /// <remarks>
        /// Reused in View Summary, View Detail, and Download buttons. 
        /// </remarks>
        /// <returns>A XMLDocument object if successfully retrieved metadata. Null if otherwise.</returns>
        private XmlDocument RetrieveSelectedMetadataFromCatalog(bool bApplyTransform)
        {
            if (cmbCswCatalog.SelectedIndex == -1)
            {
                MessageBox.Show(resourceManager.GetString("catalogNotSelected"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }

            CswCatalog catalog = (CswCatalog)cmbCswCatalog.SelectedItem;
            if (catalog == null) { throw new NullReferenceException(resourceManager.GetString("catalogNotSpecified")); }

            CswRecord record = (CswRecord)lstSearchResults.SelectedItem;
            if (record == null) throw new NullReferenceException(resourceManager.GetString("searchNotSelected"));

            // connect to catalog if not connected already
            if (!catalog.IsConnected())
            {
                string errMsg = "";
                try { catalog.Connect(); }
                catch (Exception ex) { errMsg = ex.ToString(); }
                if (!catalog.IsConnected())
                {
                    MessageBox.Show(resourceManager.GetString("catalogConnectFailed"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return null;
                }
            }
            bool isTransformed = false;
            // retrieve metadata doc by its ID
            CswSearchRequest searchRequest = new CswSearchRequest();
            searchRequest.Catalog = catalog;
            try
            {
                //MessageBox.Show(record.ID);         
                isTransformed = searchRequest.GetMetadataByID(record.ID, bApplyTransform);
                _mapServerUrl = searchRequest.GetMapServerUrl();
                //MessageBox.Show(record.FullMetadata);
            }
            catch (Exception ex)
            {
                FormMessageBox frmMessageBox = new FormMessageBox();
                frmMessageBox.Init("Failed to retrieve metadata from service: " + ex.Message,
                                    "Response from CSW service:\r\n" + searchRequest.GetResponse().ResponseXML,
                                    "Error");
                frmMessageBox.ShowDialog(this);
                return null;
            }

            CswSearchResponse response = searchRequest.GetResponse();
            CswRecord recordMetadata = response.Records[0];

            if (!isTransformed)
            {
                XmlDocument xmlDoc = new XmlDocument();
                try { xmlDoc.LoadXml(recordMetadata.FullMetadata); }
                catch (XmlException xmlEx)
                {
                    MessageBox.Show(resourceManager.GetString("loadXMLException"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return null;
                }
                return xmlDoc;
            }
            else
            {
                styledRecordResponse = recordMetadata.FullMetadata;
                return null;
            }
        }
        /// <summary>
        /// Function on click of find button
        /// </summary>
        /// <param name="sender">The sender object</param>
        /// <param name="e">The event arguments</param>
        private void btnSearch_Click(object sender, EventArgs e)
        {
            try
            {
                if (cmbCswCatalog.SelectedIndex == -1)
                {
                    MessageBox.Show(resourceManager.GetString("catalogNotSelected"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;

                }
                CswCatalog catalog = (CswCatalog)cmbCswCatalog.SelectedItem;
                if (catalog == null) { throw new NullReferenceException(resourceManager.GetString("catalogNotSpecified")); }
                if (!catalog.IsConnected())
                {
                    string errMsg = "";
                    try { catalog.Connect(); }
                    catch (Exception ex) { errMsg = ex.ToString(); }
                    if (!catalog.IsConnected())
                    {
                        MessageBox.Show(resourceManager.GetString("catalogConnectFailed"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

                // clear up result list
                lstSearchResults.DataSource = null;
                Cursor.Current = Cursors.WaitCursor;
                // genrate search criteria
                CswSearchCriteria searchCriteria = new CswSearchCriteria();
                searchCriteria.SearchText = txtSearchPhrase.Text;
                searchCriteria.StartPosition = 1;
                searchCriteria.MaxRecords = (int)nudNumOfResults.Value; ;
                searchCriteria.LiveDataAndMapOnly = (chkLiveDataAndMapOnly.CheckState == CheckState.Checked);
                searchCriteria.Envelope = null;   // place holder

                CswSearchRequest searchRequest = new CswSearchRequest();
                searchRequest.Catalog = catalog;
                searchRequest.Criteria = searchCriteria;

                searchRequest.Search();
                CswSearchResponse response = searchRequest.GetResponse();
                ArrayList alRecords = CswObjectsToArrayList(response.Records);
                if (alRecords.Count == 0)
                {
                    MessageBox.Show(resourceManager.GetString("noRecordFound"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                if (alRecords.Count > 0)
                {
                    lstSearchResults.DataSource = alRecords;
                    lstSearchResults.DisplayMember = "Title";
                    lstSearchResults.ValueMember = "ID";
                    showAllFootPrintTSBtn.Enabled = catalog.Profile.SupportSpatialBoundary;
                    clearAllFootPrintTSBtn.Enabled = catalog.Profile.SupportSpatialBoundary;
                    displayFootPrintTSBtn.Enabled = catalog.Profile.SupportSpatialBoundary;
                    zoomToFootPrintTSBtn.Enabled = catalog.Profile.SupportSpatialBoundary;
                    showAll = true;
                }
                lblResult.Text = resourceManager.GetString("resultTxt") + " (" + alRecords.Count + ")";

            }
            catch (Exception ex)
            {
                MessageBox.Show(resourceManager.GetString("searchFailed"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
        /// <summary>
        /// Retrieves the selected metadata (in search result listbox) from CSW catalog. Exception shall be thrown.
        /// </summary>
        /// <remarks>
        /// Called in View Metadata, Download Metadata, and Add to Map
        /// </remarks>
        /// <returns>A XMLDocument object if metadata was retrieved successfully. Null if otherwise.</returns>
        private XmlDocument RetrieveSelectedMetadataFromCatalog(bool bApplyTransform)
        {
            try
            {
                // validate
                if (catalogComboBox.SelectedIndex == -1) { throw new Exception(StringResources.NoCatalogSelected); }
                if (resultsListBox.SelectedIndex == -1) { throw new Exception(StringResources.NoSearchResultSelected); }
                CswCatalog catalog = (CswCatalog)catalogComboBox.SelectedItem;
                if (catalog == null) { throw new NullReferenceException(StringResources.CswCatalogIsNull); }
                CswRecord record = (CswRecord)resultsListBox.SelectedItem;
                if (record == null) throw new NullReferenceException(StringResources.CswRecordIsNull);

                // connect to catalog if needed
                if (!catalog.IsConnected())
                {
                    string errMsg = "";
                    try { catalog.Connect(); }
                    catch (Exception ex) { errMsg = ex.Message; }

                    // exit if still not connected
                    if (!catalog.IsConnected())
                    {
                        ShowErrorMessageBox(StringResources.ConnectToCatalogFailed + "\r\n" + errMsg);
                        return null;
                    }
                }

                bool isTransformed = false;

                // retrieve metadata doc by its ID
                if (_searchRequest == null) { _searchRequest = new CswSearchRequest(); }
                _searchRequest.Catalog = catalog;
                try {
                    isTransformed = _searchRequest.GetMetadataByID(record.ID, bApplyTransform);
                    _mapServerUrl = _searchRequest.GetMapServerUrl();

                }
                catch (Exception ex)
                {
                    ShowDetailedErrorMessageBox(StringResources.RetrieveMetadataFromCatalogFailed, _searchRequest.GetResponse().ResponseXML);
                    System.Diagnostics.Trace.WriteLine(StringResources.RetrieveMetadataFromCatalogFailed);
                    System.Diagnostics.Trace.WriteLine(ex.Message);
                    System.Diagnostics.Trace.WriteLine(_searchRequest.GetResponse().ResponseXML);
                    return null;
                }

                    CswSearchResponse response = _searchRequest.GetResponse();
                    CswRecord recordMetadata = response.Records[0];
                    if (recordMetadata.FullMetadata.Length == 0) { throw new Exception(StringResources.EmptyMetadata); }

                    if (!isTransformed)
                    {
                        XmlDocument xmlDoc = new XmlDocument();
                        try { xmlDoc.LoadXml(recordMetadata.FullMetadata); }
                        catch (XmlException xmlEx)
                        {
                            ShowDetailedErrorMessageBox(StringResources.LoadMetadataFailed + "\r\n" + xmlEx.Message,
                                                        recordMetadata.FullMetadata);
                            return null;
                        }
                        return xmlDoc;
                    }
                    else
                    {
                        styledRecordResponse = recordMetadata.FullMetadata;
                        return null;
                    }

            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(StringResources.RetrieveMetadataFromCatalogFailed + "\r\n" + ex.Message);
                return null;
            }
        }
        /// <summary>
        /// Retrieves the selected metadata (in search result listbox) from CSW catalog. Exception shall be thrown.
        /// </summary>
        /// <remarks>
        /// Called in View Metadata, Download Metadata, and Add to Map
        /// </remarks>
        /// <returns>A XMLDocument object if metadata was retrieved successfully. Null if otherwise.</returns>
        private void RetrieveAddToMapInfoFromCatalog()
        {
            try
            {
                // validate
                if (catalogComboBox.SelectedIndex == -1) { throw new Exception(StringResources.NoCatalogSelected); }
                if (resultsListBox.SelectedIndex == -1) { throw new Exception(StringResources.NoSearchResultSelected); }
                CswCatalog catalog = (CswCatalog)catalogComboBox.SelectedItem;
                if (catalog == null) { throw new NullReferenceException(StringResources.CswCatalogIsNull); }
                CswRecord record = (CswRecord)resultsListBox.SelectedItem;
                if (record == null) throw new NullReferenceException(StringResources.CswRecordIsNull);

                // connect to catalog if needed
                if (!catalog.IsConnected())
                {
                    string errMsg = "";
                    try { catalog.Connect(); }
                    catch (Exception ex) { errMsg = ex.Message; }

                    // exit if still not connected
                    if (!catalog.IsConnected())
                    {
                        ShowErrorMessageBox(StringResources.ConnectToCatalogFailed + "\r\n" + errMsg);
                    }
                }

                // retrieve metadata doc by its ID
                if (_searchRequest == null) { _searchRequest = new CswSearchRequest(); }
                _searchRequest.Catalog = catalog;
                try
                {
                    _searchRequest.GetAddToMapInfoByID(record.ID);
                    _mapServerUrl = _searchRequest.GetMapServerUrl();

                }
                catch (Exception ex)
                {
                    ShowDetailedErrorMessageBox(StringResources.RetrieveMetadataFromCatalogFailed, _searchRequest.GetResponse().ResponseXML);
                    System.Diagnostics.Trace.WriteLine(StringResources.RetrieveMetadataFromCatalogFailed);
                    System.Diagnostics.Trace.WriteLine(ex.Message);
                    System.Diagnostics.Trace.WriteLine(_searchRequest.GetResponse().ResponseXML);

                }

            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(StringResources.RetrieveMetadataFromCatalogFailed + "\r\n" + ex.Message);

            }
        }
        /// <summary>
        /// Search CSW catalog with the criteria defined by user
        /// </summary>
        /// <param name="sender">event sender</param>
        /// <param name="e">event args</param>
        private void FindButton_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            try
            {

                // Todo: add more validation. only minimum validation at this point.
                if (catalogComboBox.SelectedIndex == -1)
                {
                    ShowErrorMessageBox(StringResources.PleaseSelectACswCatalog);
                    return;
                }

                CswCatalog catalog = (CswCatalog)catalogComboBox.SelectedItem;
                if (catalog == null) { throw new NullReferenceException(StringResources.CswCatalogIsNull); }

                // reset GUI for search results
                ResetSearchResultsGUI();

                System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;

                if (!catalog.IsConnected())
                {
                    string errMsg = "";
                    try { catalog.Connect();
                    }
                    catch (Exception ex) { errMsg = ex.Message; }
                    if (!catalog.IsConnected())
                    {
                         sb.AppendLine("Failed to connect to Catalog");
                        ShowErrorMessageBox (StringResources.ConnectToCatalogFailed + "\r\n" + errMsg);
                        return;
                    }
                }

                // todo: need paging maganism. update SearchCriteria.StartPoistion

                // generate search criteria
                CswSearchCriteria searchCriteria = new CswSearchCriteria();
                searchCriteria.SearchText = searchPhraseTextBox.Text;
                searchCriteria.StartPosition = 1;
                searchCriteria.MaxRecords = (int)maxResultsNumericUpDown.Value;
                searchCriteria.LiveDataAndMapOnly = (liveDataAndMapsOnlyCheckBox.Checked);
                if (useCurrentExtentCheckBox.Checked)
                {
                    try { searchCriteria.Envelope = CurrentMapViewExtent(); }
                    catch (Exception ex)
                    {
                        String errMsg = StringResources.GetCurrentExtentFailed + "\r\n" +
                                            ex.Message + "\r\n" + "\r\n" +
                                            StringResources.UncheckCurrentExtentAndTryAgain;

                        sb.AppendLine(errMsg);
                        ShowErrorMessageBox(errMsg);
                        return;
                    }
                }
                else { searchCriteria.Envelope = null; }

                // search
                if (_searchRequest == null) { _searchRequest = new CswSearchRequest(); }
                _searchRequest.Catalog = catalog;
                _searchRequest.Criteria = searchCriteria;
                _searchRequest.Search();
                CswSearchResponse response = _searchRequest.GetResponse();
                // show search results
                ArrayList alRecords = CswObjectsToArrayList(response.Records);
                if (alRecords.Count > 0)
                {
                    resultsListBox.BeginUpdate();
                    resultsListBox.DataSource = alRecords;
                    resultsListBox.DisplayMember = "Title";
                    resultsListBox.ValueMember = "ID";
                    resultsListBox.SelectedIndex = 0;
                    resultsListBox.EndUpdate();
                    showAllFootprintToolStripButton.Enabled = catalog.Profile.SupportSpatialBoundary;
                    clearAllFootprinttoolStripButton.Enabled = catalog.Profile.SupportSpatialBoundary;
                    showAll = true;
                }
                else
                {
                    sb.AppendLine(StringResources.NoRecordsFound);
                    ShowErrorMessageBox(StringResources.NoRecordsFound);
                }

                resultsLabel.Text = StringResources.SearchResultsLabelText + " (" + alRecords.Count.ToString() + ")";
            }
            catch (Exception ex)
            {
                sb.AppendLine(ex.Message);
                ShowErrorMessageBox (ex.Message);
            }
            finally
            {
                Utils.logger.writeLog(sb.ToString());
                Cursor.Current = Cursors.Default;
            }
        }