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;
        }