private CompositeAnnotation DeserializeCompositeAnnotation(Type annotationType, StructuralAnnotation annotation)
        {
            var composite = (CompositeAnnotation)Activator.CreateInstance(annotationType, true);

            foreach (var prop in composite.GetType().GetAllInstanceProperties())
            {
                if (prop.CanWrite)
                {
                    var element = annotation.Content.Element(EdmConstants.TaupoAnnotationsNamespace + prop.Name);
                    if (element != null)
                    {
                        Type targetType = prop.PropertyType;

                        // if it's Nullable<T>, extract T
                        targetType = Nullable.GetUnderlyingType(targetType) ?? targetType;

                        object typedValue;
                        string stringValue = element.Value;

                        if (targetType == typeof(string))
                        {
                            typedValue = stringValue;
                        }
                        else if (targetType.IsEnum())
                        {
                            typedValue = Enum.Parse(targetType, stringValue, false);
                        }
                        else if (targetType == typeof(Guid))
                        {
                            typedValue = new Guid(stringValue);
                        }
                        else
                        {
                            ExceptionUtilities.Assert(targetType.IsPrimitive() || targetType == typeof(decimal), "Non-primitive types are not supported.");
                            typedValue = Convert.ChangeType(element.Value, targetType, CultureInfo.InvariantCulture);
                        }

                        prop.SetValue(composite, typedValue, null);
                    }
                }
            }

            return composite;
        }
        private Annotation ConvertSingleAnnotation(StructuralAnnotation annotation)
        {
            if (annotation.Content == null)
            {
                return annotation;
            }

            if (annotation.Content.Name.Namespace != EdmConstants.TaupoAnnotationsNamespace)
            {
                return annotation;
            }

            Type annotationType = this.FindAnnotationType(annotation.Content.Name);
            if (annotationType == null)
            {
                return annotation;
            }

            if (typeof(ICustomAnnotationSerializer).IsAssignableFrom(annotationType))
            {
                // since this interface is implemented, we also expect a constructor
                // which takes an XElement to be there, so let's just invoke it
                // on our XElement
                return (Annotation)Activator.CreateInstance(annotationType, annotation.Content);
            }

            if (typeof(CompositeAnnotation).IsAssignableFrom(annotationType))
            {
                return this.DeserializeCompositeAnnotation(annotationType, annotation);
            }

            // any other annotation type - just return it
            return annotation;
        }