// This method validates xsi:type="dcterms:W3CDTF"
        // The value of xsi:type is a qualified name. It should have a prefix that matches
        //  the xml namespace (ns) within the scope and the name that matches name
        // The comparisons should be case-sensitive comparisons
        internal static void ValidateXsiType(XmlReader reader, object ns, string name)
        {
            // Get the value of xsi;type
            string typeValue = reader.GetAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                   PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

            // Missing xsi:type
            if (typeValue == null)
            {
                throw new XmlException(SR.Format(SR.UnknownDCDateTimeXsiType, reader.Name),
                                       null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
            }

            int index = typeValue.IndexOf(':');

            // The value of xsi:type is not a qualified name
            if (index == -1)
            {
                throw new XmlException(SR.Format(SR.UnknownDCDateTimeXsiType, reader.Name),
                                       null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
            }

            // Check the following conditions
            //  The namespace of the prefix (string before ":") matches "ns"
            //  The name (string after ":") matches "name"
            if (!object.ReferenceEquals(ns, reader.LookupNamespace(typeValue.Substring(0, index))) ||
                string.CompareOrdinal(name, typeValue.Substring(index + 1, typeValue.Length - index - 1)) != 0)
            {
                throw new XmlException(SR.Format(SR.UnknownDCDateTimeXsiType, reader.Name),
                                       null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
            }
        }
        private void WriteXmlStartTagsForPackageProperties()
        {
            _xmlWriter.WriteStartDocument();

            // <coreProperties
            _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(PackageXmlEnum.CoreProperties),                  // local name
                                         PackageXmlStringTable.GetXmlString(PackageXmlEnum.PackageCorePropertiesNamespace)); // namespace

            // xmlns:dc
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCorePropertiesNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCorePropertiesNamespace));

            // xmlns:dcterms
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublincCoreTermsNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));
            // xmlns:xsi
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));
        }
        // Write the property elements and clear _dirty.
        private void SerializeDirtyProperties()
        {
            Debug.Assert(_xmlWriter != null);

            // Create a property element for each non-null entry.
            foreach (KeyValuePair <PackageXmlEnum, object> entry in _propertyDictionary)
            {
                Debug.Assert(entry.Value != null);

                PackageXmlEnum propertyNamespace = PackageXmlStringTable.GetXmlNamespace(entry.Key);

                _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(entry.Key),
                                             PackageXmlStringTable.GetXmlString(propertyNamespace));

                if (entry.Value is Nullable <DateTime> )
                {
                    if (propertyNamespace == PackageXmlEnum.DublinCoreTermsNamespace)
                    {
                        // xsi:type=
                        _xmlWriter.WriteStartAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                       PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

                        // "dcterms:W3CDTF"
                        _xmlWriter.WriteQualifiedName(W3cdtf,
                                                      PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));

                        _xmlWriter.WriteEndAttribute();
                    }

                    // Use sortable ISO 8601 date/time pattern. Include second fractions down to the 100-nanosecond interval,
                    // which is the definition of a "tick" for the DateTime type.
                    _xmlWriter.WriteString(XmlConvert.ToString(((Nullable <DateTime>)entry.Value).Value.ToUniversalTime(), "yyyy-MM-ddTHH:mm:ss.fffffffZ"));
                }
                else
                {
                    // The following uses the fact that ToString is virtual.
                    _xmlWriter.WriteString(entry.Value.ToString());
                }

                _xmlWriter.WriteEndElement();
            }

            // Mark properties as saved.
            _dirty = false;
        }