/// <summary>
        /// Reflects all types in the AssembyDefn's addembly and extracts all the types in theasembly in the required
        /// namespace that have the PDFParsableComponent attibute defined on the class - adding them to the NamespaceDefn
        /// </summary>
        /// <param name="ns"></param>
        /// <param name="assmdefn"></param>
        /// <param name="nsdefn"></param>
        private static void PopulateNamespaceFromAssembly(string ns, AssemblyDefn assmdefn, NamespaceDefn nsdefn)
        {
            if (assmdefn == null)
            {
                throw new ArgumentNullException("assmdefn");
            }
            if (assmdefn.InnerAssembly == null)
            {
                throw new ArgumentNullException("assmdefn.InnerAssembly");
            }

            if (null == nsdefn)
            {
                throw new ArgumentNullException("nsdefn");
            }

            Type[] all = assmdefn.InnerAssembly.GetTypes();
            foreach (Type t in all)
            {
                if (string.Equals(t.Namespace, ns))
                {
                    object[] attrs = t.GetCustomAttributes(typeof(PDFParsableComponentAttribute), false);
                    if (null != attrs && attrs.Length > 0)
                    {
                        PDFParsableComponentAttribute compattr = (PDFParsableComponentAttribute)attrs[0];
                        string name = compattr.ElementName;
                        if (string.IsNullOrEmpty(name))
                        {
                            name = t.Name;
                        }

                        nsdefn.Add(name, t);

                        //check to see if it has a remote name too
                        attrs = t.GetCustomAttributes(typeof(PDFRemoteParsableComponentAttribute), false);
                        if (null != attrs && attrs.Length > 0)
                        {
                            PDFRemoteParsableComponentAttribute remattr = (PDFRemoteParsableComponentAttribute)attrs[0];
                            string remotename = remattr.ElementName;
                            if (string.IsNullOrEmpty(name))
                            {
                                remotename = t.Name + "-Ref";
                            }
                            nsdefn.RemoteTypes.Add(remotename, name);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Unsafe method to extract a type based on a declared assembly namespace.
        /// Must be called from within a thread safe block
        /// </summary>
        /// <param name="elementname"></param>
        /// <param name="assemblyQualifiedNamespace"></param>
        /// <param name="isremote"></param>
        /// <returns></returns>
        private static Type UnsafeGetType(string elementname, string assemblyQualifiedNamespace, bool throwOnNotFound, out bool isremote)
        {
            if (null == assemblyQualifiedNamespace)
            {
                assemblyQualifiedNamespace = string.Empty;
            }
            if (string.IsNullOrEmpty(elementname))
            {
                throw new ArgumentNullException("elementname");
            }

            AssemblyDefn  assmdefn;
            NamespaceDefn nsdefn;
            Type          t;

            string assm;
            string ns;

            ExtractAssemblyAndNamespace(assemblyQualifiedNamespace, out assm, out ns);
            if (string.IsNullOrEmpty(assm))
            {
                if (throwOnNotFound)
                {
                    throw new PDFParserException(String.Format(Errors.ParserDoesNotHaveAssemblyRegisteredForNamespace, assemblyQualifiedNamespace, elementname));
                }
                else
                {
                    isremote = false;
                    return(null);
                }
            }


            if (!_application.TryGetValue(assm, out assmdefn))
            {
                assmdefn = new AssemblyDefn();
                Assembly found = GetAssemblyByName(assm);
                if (null == found)
                {
                    if (throwOnNotFound)
                    {
                        throw new PDFParserException(String.Format(Errors.ParserCannotFindAssemblyWithName, assm));
                    }
                    else
                    {
                        isremote = false;
                        return(null);
                    }
                }
                assmdefn.InnerAssembly = found;
                _application[assm]     = assmdefn;
            }

            if (!assmdefn.TryGetValue(ns, out nsdefn))
            {
                nsdefn = new NamespaceDefn();
                PopulateNamespaceFromAssembly(ns, assmdefn, nsdefn);
                assmdefn[ns] = nsdefn;
            }

            if (!nsdefn.TryGetValue(elementname, out t))
            {
                string actual;
                //it's not an actual type so check the remote types and if it's still not fount throw an exception
                if (!nsdefn.RemoteTypes.TryGetValue(elementname, out actual) || !nsdefn.TryGetValue(actual, out t))
                {
                    if (throwOnNotFound)
                    {
                        throw new PDFParserException(String.Format(Errors.NoPDFComponentDeclaredWithNameInNamespace, elementname, assemblyQualifiedNamespace));
                    }
                    else
                    {
                        isremote = false;
                        return(null);
                    }
                }
                else
                {
                    isremote = true;
                }
            }
            else
            {
                isremote = false;
            }

            return(t);
        }