public DynamicReadTravellerMembers(ITypeProvider provider)
        {
            var visitArgsType = typeof(VisitArgs).GetTypeInfo();

            VisitArgsCollectionItem              = new ILStaticFieldVariable(visitArgsType.GetField("CollectionItem"));
            VisitArgsDictionaryKey               = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryKey"));
            VisitArgsDictionaryValue             = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection      = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection      = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey   = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey   = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInDictionaryValue"));

            var readVisitorType = typeof(IReadVisitor).GetTypeInfo();

            VisitorTryVisit = readVisitorType.GetMethod("TryVisit");
            VisitorLeave    = readVisitorType.GetMethod("Leave");

            VisitorTryVisitValue = new Dictionary <Type, MethodInfo>();
            Nullable             = new Dictionary <Type, NullableMembers>();

            foreach (var method in readVisitorType.GetMethods()
                     .Where(m => m.Name == "TryVisitValue"))
            {
                var valueType = method.GetParameters()[1].ParameterType;
                if (valueType.IsByRef)
                {
                    valueType = valueType.GetElementType();
                }
                var valueTypeExt = provider.Extend(valueType);

                VisitorTryVisitValue.Add(valueType, method);
                if (valueTypeExt.Classification == TypeClassification.Nullable)
                {
                    var innerType = valueTypeExt.Container.AsNullable().ElementType;
                    VisitorTryVisitValue.Add(innerType, method);

                    var nullableMembers = new NullableMembers(innerType);
                    Nullable.Add(innerType, nullableMembers);
                    Nullable.Add(valueType, nullableMembers);
                }
            }

            EnumeratorMoveNext = typeof(IEnumerator).GetTypeInfo().GetMethod("MoveNext");
            DisposableDispose  = typeof(IDisposable).GetTypeInfo().GetMethod("Dispose");

            ExceptionNoDictionaryValue = typeof(InvalidGraphException).GetTypeInfo().GetMethod("NoDictionaryValue");
        }
        public DynamicReadTravellerMembers()
        {
            var visitArgsType = typeof(VisitArgs);
            VisitArgsCollectionItem = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionItem"));
            VisitArgsDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryKey"));
            VisitArgsDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryValue"));

            var readVisitorType = typeof(IReadVisitor);
            VisitorTryVisit = readVisitorType.GetMethod("TryVisit");
            VisitorLeave = readVisitorType.GetMethod("Leave");

            VisitorTryVisitValue = new Dictionary<Type, MethodInfo>();
            Nullable = new Dictionary<Type, NullableMembers>();

            foreach (var method in readVisitorType.GetMethods()
                .Where(m => m.Name == "TryVisitValue")) {

                var valueType = method.GetParameters()[1].ParameterType;
                if (valueType.IsByRef) valueType = valueType.GetElementType();
                var valueTypeExt = valueType.Extend();

                VisitorTryVisitValue.Add(valueType, method);
                if (valueTypeExt.Class == TypeClass.Nullable) {
                    var innerType = valueTypeExt.Container.AsNullable().ElementType;
                    VisitorTryVisitValue.Add(innerType, method);

                    var nullableMembers = new NullableMembers(innerType);
                    Nullable.Add(innerType, nullableMembers);
                    Nullable.Add(valueType, nullableMembers);
                }
            }

            EnumeratorMoveNext = typeof(IEnumerator).GetMethod("MoveNext");
            DisposableDispose = typeof(IDisposable).GetMethod("Dispose");

            ExceptionNoDictionaryValue = typeof (InvalidGraphException).GetMethod("NoDictionaryValue");
        }