/// ------------------------------------------------------------------------------------
        private bool CreateWordEntriesFromAllomorphs(IPaLexEntry lxEntry, RecordCacheEntry recCacheEntry)
        {
            var skip1 = true;

            foreach (var allo in lxEntry.Allomorphs.Where(p => p != null))
            {
                if (skip1)
                {
                    skip1 = false;
                    continue;
                }
                var eticValue = allo.GetString(m_phoneticWsId);
                if (eticValue != null)
                {
                    var wentry = new WordCacheEntry(recCacheEntry, m_phoneticFieldName);
                    wentry.SetValue(m_phoneticFieldName, eticValue);
                    if (m_audioWsId != null)
                    {
                        string audioFile = allo.GetString(m_audioWsId);
                        if (audioFile != null)
                        {
                            wentry["AudioFile"] = audioFile;
                        }
                    }

                    wentry.Guid = new Guid(lxEntry.Guid.ToString());
                    recCacheEntry.WordEntries.Add(wentry);
                }
            }

            return(recCacheEntry.WordEntries.Count > 0);
        }
        /// ------------------------------------------------------------------------------------
        private void ReadSinglePronunciation(IPaLexPronunciation pro, WordCacheEntry wentry)
        {
            var mapping = m_dataSource.FieldMappings.SingleOrDefault(m => m.NameInDataSource == "CV-Pattern-Source");

            if (mapping != null)
            {
                wentry.SetValue(mapping.NameInDataSource, pro.CVPattern);
            }

            mapping = m_dataSource.FieldMappings.SingleOrDefault(m => m.NameInDataSource == "Tone");
            if (mapping != null)
            {
                wentry.SetValue(mapping.NameInDataSource, pro.Tone);
            }

            mapping = m_dataSource.FieldMappings.SingleOrDefault(m => m.NameInDataSource == "Location");
            if (mapping != null)
            {
                wentry.SetValue(mapping.NameInDataSource,
                                GetPossibilityValue(pro.Location, false));
            }

            if (!pro.MediaFiles.Any())
            {
                return;
            }

            // TODO: Verify that the media file is audio.
            var mediaFile = pro.MediaFiles.ElementAt(0);

            // TODO: Figure out a way to deal with more than one media file and label.
            wentry.SetValue("AudioFile", mediaFile.AbsoluteInternalPath);

            mapping = m_dataSource.FieldMappings.SingleOrDefault(m => m.NameInDataSource == "AudioFileLabel");
            if (mapping != null)
            {
                wentry.SetValue("AudioFileLabel", GetMultiStringValue(mediaFile.Label, mapping.FwWsId));
            }
        }
        /// ------------------------------------------------------------------------------------
        private bool CreateWordEntriesFromPronunciations(IPaLexEntry lxEntry, RecordCacheEntry recCacheEntry)
        {
            foreach (var pro in lxEntry.Pronunciations.Where(p => p.Form != null))
            {
                var eticValue = pro.Form.GetString(m_phoneticWsId);
                if (eticValue != null)
                {
                    var wentry = new WordCacheEntry(recCacheEntry, m_phoneticFieldName);
                    wentry.SetValue(m_phoneticFieldName, eticValue);
                    wentry.Guid = new Guid(lxEntry.Guid.ToString());
                    ReadSinglePronunciation(pro, wentry);
                    recCacheEntry.WordEntries.Add(wentry);
                }
            }

            return(recCacheEntry.WordEntries.Count > 0);
        }
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Reads all the data for a lex. entry that get written to word cache entries (e.g.
        /// phonetic, audio file info., etc.)
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private bool ReadWordEntryFieldsFromLexEntry(IPaLexEntry lxEntry, RecordCacheEntry recCacheEntry)
        {
            if (m_fwDsInfo.PhoneticStorageMethod == FwDBUtils.PhoneticStorageMethod.AllPronunciationFields)
            {
                return(CreateWordEntriesFromPronunciations(lxEntry, recCacheEntry));
            }

            recCacheEntry.Guid = new Guid(lxEntry.Guid.ToString());

            var pro = (!lxEntry.Pronunciations.Any() ? null : lxEntry.Pronunciations.ElementAt(0));

            string eticValue = null;

            if (m_fwDsInfo.PhoneticStorageMethod == FwDBUtils.PhoneticStorageMethod.LexemeForm)
            {
                if (m_vernCustom)
                {
                    var customvalues = m_customfield.CustomValues.FindAll(m => m.Guid == lxEntry.Guid.ToString());
                    foreach (var nm in customvalues.Select(m => m.CustomFields).Select(value => value.SingleOrDefault(m => m.Name == m_vernPhonetic.Name)).Where(nm => nm != null))
                    {
                        eticValue = nm.Value;
                        break;
                    }
                }
                else
                {
                    switch (m_vernPhonetic != null ? m_vernPhonetic.Name : "LexemeForm")
                    {
                    case "LexemeForm": eticValue = GetMultiStringValue(lxEntry.LexemeForm, m_phoneticWsId); break;

                    case "Variants":
                        eticValue = lxEntry.Variants.Where(v => v.VariantForm != null).Select(v => v.VariantForm.GetString(m_phoneticWsId)).FirstOrDefault();
                        break;

                    case "ComplexForms":
                        eticValue = GetCommaDelimitedList(lxEntry.ComplexForms.Select(c => c.GetString(m_phoneticWsId)));
                        break;

                    case "Components":
                        eticValue = lxEntry.ComplexFormInfo.Select(ci => GetCommaDelimitedList(ci.Components)).FirstOrDefault();
                        break;

                    case "Allomorphs":
                        return(CreateWordEntriesFromAllomorphs(lxEntry, recCacheEntry));

                    case "CitationForm":
                        eticValue = GetMultiStringValue(lxEntry.CitationForm, m_phoneticWsId);
                        break;
                    }
                }
                //if (lxEntry.LexemeForm != null)
                //    eticValue = lxEntry.LexemeForm.GetString(m_phoneticWsId);
            }
            else
            {
                if (pro != null && pro.Form != null)
                {
                    eticValue = pro.Form.GetString(m_phoneticWsId);
                }
            }

            if (eticValue == null)
            {
                return(false);
            }

            var wentry = new WordCacheEntry(recCacheEntry, m_phoneticFieldName);

            wentry.SetValue(m_phoneticFieldName, eticValue);

            if (pro != null)
            {
                ReadSinglePronunciation(pro, wentry);
            }

            if (wentry.GetField("AudioFile", false) == null)
            {
                SearchForAudioWritingSystems(wentry, lxEntry, pro);
            }

            recCacheEntry.WordEntries.Add(wentry);
            return(true);
        }
        /// ------------------------------------------------------------------------------------
        private void HandleReadingFwData(SqlDataReader reader)
        {
            if (reader == null || reader.IsClosed)
            {
                return;
            }

            // First, get a list of the fields returned from the query
            // and translate those to their corresponding PA fields.
            var fieldNames = new Dictionary <int, string>();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                if (m_dataSource.FieldMappings.Any(m => m.Field.Name == reader.GetName(i)))
                {
                    fieldNames[i] = reader.GetName(i);
                }
            }

            var eticField     = m_dataSource.FieldMappings.FirstOrDefault(m => m.Field.Type == FieldType.Phonetic);
            var eticFieldName = (eticField != null ? eticField.PaFieldName : null);

            while (reader.Read())
            {
                // Make a new record entry for each row returned from the query.
                var recCacheEntry = new RecordCacheEntry(false, m_project)
                {
                    DataSource   = m_dataSource,
                    NeedsParsing = false,
                    WordEntries  = new List <WordCacheEntry>(),
                };

                var wentry = new WordCacheEntry(recCacheEntry);

                // Read the data for all columns having a mapped field.
                foreach (var kvp in fieldNames)
                {
                    var dbValue = reader[kvp.Key];

                    if (dbValue is DBNull)
                    {
                        continue;
                    }

                    // Put the phonetic field in a word entry and all the other data in the
                    // record entry.
                    if (kvp.Value != eticFieldName)
                    {
                        recCacheEntry.SetValue(kvp.Value, dbValue.ToString());
                    }
                    else
                    {
                        wentry.SetValue(kvp.Value, dbValue.ToString());
                    }
                }

                var guid = reader["Guid"];
                if (!(guid is DBNull))
                {
                    recCacheEntry.Guid = new Guid(guid.ToString());
                }

                // Add the entries to the caches.
                recCacheEntry.WordEntries.Add(wentry);
                m_recCache.Add(recCacheEntry);
            }
        }