internal ContentTypeReader[] LoadAssetReaders(ContentReader reader)
        {
            // Trick to prevent the linker removing the code, but not actually execute the code
            if (falseflag)
            {
                // Dummy variables required for it to work on iDevices ** DO NOT DELETE **
                // This forces the classes not to be optimized out when deploying to iDevices
                var hByteReader              = new ByteReader();
                var hSByteReader             = new SByteReader();
                var hDateTimeReader          = new DateTimeReader();
                var hDecimalReader           = new DecimalReader();
                var hBoundingSphereReader    = new BoundingSphereReader();
                var hBoundingFrustumReader   = new BoundingFrustumReader();
                var hRayReader               = new RayReader();
                var hCharListReader          = new ListReader <char>();
                var hRuneListReader          = new ListReader <Rune>();
                var hNullableRectReader      = new NullableReader <Rectangle>();
                var hRectangleArrayReader    = new ArrayReader <Rectangle>();
                var hRectangleListReader     = new ListReader <Rectangle>();
                var hVector3ArrayReader      = new ArrayReader <Vector3>();
                var hVector3ListReader       = new ListReader <Vector3>();
                var hVector2ArrayReader      = new ArrayReader <Vector2>();
                var hVector2ListReader       = new ListReader <Vector2>();
                var hStringListReader        = new ListReader <StringReader>();
                var hIntListReader           = new ListReader <int>();
                var hSpriteFontReader        = new SpriteFontReader();
                var hTexture2DReader         = new Texture2DReader();
                var hCharReader              = new CharReader();
                var hRuneReader              = new RuneReader();
                var hRectangleReader         = new RectangleReader();
                var hStringReader            = new StringReader();
                var hVector2Reader           = new Vector2Reader();
                var hVector3Reader           = new Vector3Reader();
                var hVector4Reader           = new Vector4Reader();
                var hCurveReader             = new CurveReader();
                var hIndexBufferReader       = new IndexBufferReader();
                var hBoundingBoxReader       = new BoundingBoxReader();
                var hMatrixReader            = new MatrixReader();
                var hBasicEffectReader       = new BasicEffectReader();
                var hVertexBufferReader      = new VertexBufferReader();
                var hAlphaTestEffectReader   = new AlphaTestEffectReader();
                var hEnumSpriteEffectsReader = new EnumReader <Graphics.SpriteFlip>();
                var hArrayFloatReader        = new ArrayReader <float>();
                var hArrayMatrixReader       = new ArrayReader <Matrix4x4>();
                var hEnumBlendReader         = new EnumReader <Graphics.Blend>();
                var hEffectMaterialReader    = new EffectMaterialReader();
                var hExternalReferenceReader = new ExternalReferenceReader();
                var hSoundEffectReader       = new SoundEffectReader();
                var hSongReader              = new SongReader();
                var hModelReader             = new ModelReader();
                var hInt32Reader             = new Int32Reader();
                var hEffectReader            = new EffectReader();
                var hSingleReader            = new SingleReader();

                // At the moment the Video class doesn't exist
                // on all platforms... Allow it to compile anyway.
#if (IOS && !TVOS) || MONOMAC || (WINDOWS && !OPENGL) || WINDOWS_UAP
                var hVideoReader = new VideoReader();
#endif
            }

            // The first content byte i read tells me the number of content readers in this XNB file
            var numberOfReaders = reader.Read7BitEncodedInt();
            var contentReaders  = new ContentTypeReader[numberOfReaders];
            var needsInitialize = new BitArray(numberOfReaders);
            _contentReaders = new Dictionary <Type, ContentTypeReader>(numberOfReaders);

            // Lock until we're done allocating and initializing any new
            // content type readers...  this ensures we can load content
            // from multiple threads and still cache the readers.
            lock (SyncRoot)
            {
                // For each reader in the file,
                // we read out the length of the string which contains the type of the reader,
                // then we read out the string.
                // Finally we instantiate an instance of that reader using reflection
                for (var i = 0; i < numberOfReaders; i++)
                {
                    // This string tells us what reader we need to decode the following data
                    // string readerTypeString = reader.ReadString();
                    string originalReaderTypeString = reader.ReadString();

                    if (ReaderFactories.TryGetValue(originalReaderTypeString, out var readerFactory))
                    {
                        contentReaders[i]  = readerFactory.Invoke();
                        needsInitialize[i] = true;
                    }
                    else
                    {
                        //System.Diagnostics.Debug.WriteLine(originalReaderTypeString);

                        // Need to resolve namespace differences
                        string readerTypeString = originalReaderTypeString;
                        readerTypeString = PrepareType(readerTypeString);

                        var l_readerType = Type.GetType(readerTypeString);
                        if (l_readerType != null)
                        {
                            if (!ContentReaderCache.TryGetValue(l_readerType, out var typeReader))
                            {
                                try
                                {
                                    typeReader = (ContentTypeReader)l_readerType.GetDefaultConstructor().Invoke(null);
                                }
                                catch (TargetInvocationException ex)
                                {
                                    // If you are getting here, the Mono runtime is most likely not able to JIT the type.
                                    // In particular, MonoTouch needs help instantiating types
                                    // that are only defined in strings in XNB files.
                                    throw new InvalidOperationException(
                                              $"Failed to get default constructor for {nameof(ContentTypeReader)}. " +
                                              $"To work around, add a factory function " +
                                              $"(with {nameof(ContentTypeReaderManager)}.{nameof(AddReaderFactory)}) " +
                                              "with the following type string: " + originalReaderTypeString, ex);
                                }

                                needsInitialize[i] = true;

                                ContentReaderCache.Add(l_readerType, typeReader);
                            }

                            contentReaders[i] = typeReader;
                        }
                        else
                        {
                            throw new ContentLoadException(
                                      $"Could not find {nameof(ContentTypeReader)} Type. " +
                                      "Please ensure the name of the assembly " +
                                      "that contains the type matches the assembly in the full type name: " +
                                      originalReaderTypeString + " (" + readerTypeString + ")");
                        }
                    }

                    var targetType = contentReaders[i].TargetType;
                    if (targetType != null)
                    {
                        if (!_contentReaders.ContainsKey(targetType))
                        {
                            _contentReaders.Add(targetType, contentReaders[i]);
                        }
                    }

                    // I think the next 4 bytes refer to the "Version" of the type reader,
                    // although it always seems to be zero
                    reader.ReadInt32();
                }

                // Initialize any new readers.
                for (int i = 0; i < contentReaders.Length; i++)
                {
                    if (needsInitialize.Get(i))
                    {
                        contentReaders[i].Initialize(this);
                    }
                }
            }

            return(contentReaders);
        }
        private static ReadElement GetElementReader(ContentTypeReaderManager manager, MemberInfo member)
        {
            var property = member as PropertyInfo;
            var field    = member as FieldInfo;

            Debug.Assert(field != null && property != null);

            if (property != null)
            {
                // Properties must have at least a getter.
                if (!property.CanRead)
                {
                    return(null);
                }

                // Skip over indexer properties.
                if (property.GetIndexParameters().Any())
                {
                    return(null);
                }
            }

            // Are we explicitly asked to ignore this item?
            if (member.GetCustomAttribute <ContentSerializerIgnoreAttribute>() != null)
            {
                return(null);
            }

            var contentSerializerAttribute = member.GetCustomAttribute <ContentSerializerAttribute>();

            if (contentSerializerAttribute == null)
            {
                if (property != null)
                {
                    // There is no ContentSerializerAttribute, so non-public
                    // properties cannot be deserialized.
                    if (!ReflectionHelpers.PropertyIsPublic(property))
                    {
                        return(null);
                    }

                    // If the read-only property has a type reader,
                    // and CanDeserializeIntoExistingObject is true,
                    // then it is safe to deserialize into the existing object.
                    if (!property.CanWrite)
                    {
                        var typeReader = manager.GetTypeReader(property.PropertyType);
                        if (typeReader == null || !typeReader.CanDeserializeIntoExistingObject)
                        {
                            return(null);
                        }
                    }
                }
                else
                {
                    // There is no ContentSerializerAttribute, so non-public
                    // fields cannot be deserialized.
                    if (!field.IsPublic)
                    {
                        return(null);
                    }

                    // evolutional: Added check to skip initialise only fields
                    if (field.IsInitOnly)
                    {
                        return(null);
                    }
                }
            }

            Type elementType;
            Action <object, object> setter;

            if (property != null)
            {
                elementType = property.PropertyType;
                if (property.CanWrite)
                {
                    setter = (o, v) => property.SetValue(o, v, null);
                }
                else
                {
                    setter = (o, v) => { }
                };
            }
            else
            {
                elementType = field.FieldType;
                setter      = field.SetValue;
            }

            // Shared resources get special treatment.
            if (contentSerializerAttribute != null && contentSerializerAttribute.SharedResource)
            {
                return((input, parent) =>
                {
                    input.ReadSharedResource <object>((value) => setter(parent, value));
                });
            }

            // We need to have a reader at this point.
            var reader = manager.GetTypeReader(elementType);

            if (reader == null)
            {
                if (elementType == typeof(Array))
                {
                    reader = new ArrayReader <Array>();
                }
                else
                {
                    throw new ContentLoadException(
                              $"Content reader could not be found for {elementType.FullName} type.");
                }
            }

            // We use the construct delegate to pick the correct existing
            // object to be the target of deserialization.
            Func <object, object> construct = parent => null;

            if (property != null && !property.CanWrite)
            {
                construct = parent => property.GetValue(parent, null);
            }

            return((input, parent) =>
            {
                var existing = construct.Invoke(parent);
                var obj2 = input.ReadObject(reader, existing);
                setter(parent, obj2);
            });
        }