private ObjectValues Build(IParsingContext context, Object current, ClassInfo type, Object[] values, IDictionary<Int32, ObjectValues> cache)
        {
            // Check (and return) cached values early so we don't enter an infinite
            // loop while resolving references to ourself.
            var hasObjectId = current as ISerializedObject;
            if (hasObjectId != null && cache.ContainsKey(hasObjectId.ObjectId)) {
                return cache[hasObjectId.ObjectId];
            }

            String libraryName = null;
            var hasLibraryId = current as IHasLibraryId;
            if (hasLibraryId != null) {
                var library = context.GetLibrary(hasLibraryId.LibraryId);
                libraryName = library.LibraryName;
            }

            var target = new ObjectValues(libraryName, type.Name);
            if (hasObjectId != null) {
                // Store the item in the cache early to avoid infinite loops if
                // we have a reference to ourself.
                cache[hasObjectId.ObjectId] = target;
            }

            for(var i = 0; i < values.Length; ++i){
                var memberName = type.Members[i];
                var value = values[i];

                while(value is IValueHolder) {
                    value = ((IValueHolder)value).GetValue(context);
                }

                var nestedTypeHolder = value as ITypeHolder;
                if (nestedTypeHolder != null) {
                    var nestedType = nestedTypeHolder.GetClassInfo(context);
                    var nestedValues = ((ClassRecordBase)value).Values;

                    Object result;
                    if (TryBuildSystemType(context, nestedType, nestedValues, out result))
                        target[memberName] = result;
                    else
                        target[memberName] = Build(context, value, nestedType, nestedValues, cache);
                } else {
                    target[memberName] = value;
                }
            }

            return target;
        }
        private Boolean TryBuildSystemType(IParsingContext context, ClassInfo classInfo, Object[] values, out Object result)
        {
            Func<String, Object> V = name => classInfo.GetValue(name, values);

            if (classInfo.Name == "System.Guid") {
                result = new Guid((Int32)V("_a"), (Int16)V("_b"), (Int16)V("_c"), (Byte)V("_d"), (Byte)V("_e"), (Byte)V("_f"), (Byte)V("_g"), (Byte)V("_h"), (Byte)V("_i"), (Byte)V("_j"), (Byte)V("_k"));
                return true;
            }

            result = null;
            return false;
        }
 protected ClassWithMembersAndTypesBase(IParsingContext context)
 {
     ClassInfo = new ClassInfo(context);
     MemberTypeInfo = new MemberTypeInfo(context, ClassInfo.Members.Length);
 }