/// <summary>
        /// Get properties and add them to a list.
        /// </summary>
        /// <param name="obs"></param>
        /// <returns></returns>
        public static Dictionary <string, string> ExtractProperties(ISpeciesObservation obs)
        {
            Dictionary <string, string> propertyList = new Dictionary <string, string>();
            string propertyValueAsString             = null;
            Type   type = obs.GetType();

            PropertyInfo[] propInfos = type.GetProperties();
            for (int i = 0; i < propInfos.Length; i++)
            {
                PropertyInfo pi        = (PropertyInfo)propInfos.GetValue(i);
                string       propName  = pi.Name;
                object       propValue = pi.GetValue(obs, null);
                if (propValue is ISpeciesObservationConservation || propValue is ISpeciesObservationEvent ||
                    propValue is ISpeciesObservationGeologicalContext ||
                    propValue is ISpeciesObservationIdentification || propValue is ISpeciesObservationLocation ||
                    propValue is ISpeciesObservationMeasurementOrFact ||
                    propValue is ISpeciesObservationOccurrence || propValue is ISpeciesObservationProject ||
                    propValue is ISpeciesObservationResourceRelationship ||
                    propValue is ISpeciesObservationTaxon)
                {
                    PropertyInfo[] subSpeciesPropertyInfos = null;
                    if (propValue is ISpeciesObservationConservation)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationConservation).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationEvent)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationEvent).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationGeologicalContext)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationGeologicalContext).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationIdentification)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationIdentification).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationLocation)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationLocation).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationMeasurementOrFact)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationMeasurementOrFact).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationOccurrence)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationOccurrence).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationProject)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationProject).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationResourceRelationship)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationResourceRelationship).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationTaxon)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationTaxon).GetProperties();
                    }
                    else
                    {
                        subSpeciesPropertyInfos = new PropertyInfo[] { };
                    }

                    //Add property
                    AddClassPropertiesToList(obs, subSpeciesPropertyInfos, propValue, propertyList);
                }
                else
                {
                    propertyValueAsString = GetPropertyValueAsString(propValue);
                    propertyList.Add(propName, propertyValueAsString);
                }
            }
            return(propertyList);
        }
        /// <summary>
        /// Copies the data from observation to model.
        /// The observation object contains hierarchical data, while the model is flat.
        /// </summary>
        /// <param name="observation">The observation.</param>
        /// <param name="model">The model.</param>
        /// <param name="speciesObservationFieldDescriptions"></param>
        private void CopyDataFromObservationToModel(
            ISpeciesObservation observation,
            SpeciesObservationViewModel model,
            ISpeciesObservationFieldDescriptionsViewModel speciesObservationFieldDescriptions)
        {
            // Create detalis list out of propery and resource string
            Type type = observation.GetType();

            PropertyInfo[] propInfos = type.GetProperties();
            for (int i = 0; i < propInfos.Length; i++)
            {
                PropertyInfo pi           = (PropertyInfo)propInfos.GetValue(i);
                string       propertyName = pi.Name;
                object       propValue    = pi.GetValue(observation, null);
                if (propValue is ISpeciesObservationConservation || propValue is ISpeciesObservationEvent ||
                    propValue is ISpeciesObservationGeologicalContext ||
                    propValue is ISpeciesObservationIdentification || propValue is ISpeciesObservationLocation ||
                    propValue is ISpeciesObservationMeasurementOrFact ||
                    propValue is ISpeciesObservationOccurrence || propValue is ISpeciesObservationProject ||
                    propValue is ISpeciesObservationResourceRelationship ||
                    propValue is ISpeciesObservationTaxon)
                {
                    PropertyInfo[] subSpeciesPropertyInfos = null;
                    if (propValue is ISpeciesObservationConservation)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationConservation).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationEvent)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationEvent).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationGeologicalContext)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationGeologicalContext).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationIdentification)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationIdentification).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationLocation)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationLocation).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationMeasurementOrFact)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationMeasurementOrFact).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationOccurrence)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationOccurrence).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationProject)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationProject).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationResourceRelationship)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationResourceRelationship).GetProperties();
                    }
                    else if (propValue is ISpeciesObservationTaxon)
                    {
                        subSpeciesPropertyInfos = typeof(ISpeciesObservationTaxon).GetProperties();
                    }

                    CopyDataFromSubProperty(observation, subSpeciesPropertyInfos, propValue, model);
                }
                else
                {
                    //Get string value for property
                    string propertyValue = GetPropertyValueAsString(propValue);

                    PropertyInfo modelPi;
                    if (ObservationDarwinCoreViewModelPropertiesDictionary.TryGetValue(propertyName, out modelPi))
                    {
                        modelPi.SetValue(model, propertyValue, null);
                    }
                }
            }

            CopyProjectParametersToModel(observation, model, speciesObservationFieldDescriptions);
        }