/// <summary>
        /// Visit the given builder <c>T</c> and optionally mutate it using
        /// information contained within the given Type.
        /// </summary>
        /// <param name="builder">
        /// The builder being visited.
        /// </param>
        /// <param name="type">
        /// The Type used to enrich the builder.
        /// </param>
        public virtual void Visit(T builder, Type type)
        {
            Portable portable = Attribute.GetCustomAttribute(type, typeof(Portable)) as Portable;

            // fast escape switch
            if (portable == null)
            {
                return;
            }

            // get header level information
            bool autoIndex = m_autoIndex;

            builder.SetType(type);

            // BindingFlags for member access
            const BindingFlags bindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            // get property level information
            PropertyInfo[] props          = type.GetProperties(bindings);
            IList <string> fieldsExcluded = new List <string>(props.Length);

            for (int i = 0; i < props.Length; ++i)
            {
                PropertyInfo     prop      = props[i];
                PortableProperty attribute = Attribute.GetCustomAttribute(prop, typeof(PortableProperty)) as PortableProperty;
                if (attribute == null)
                {
                    continue;
                }

                string propName = prop.Name;
                string mangled  = NameManglers.PROPERTY_MANGLER.Mangle(propName);
                ICodec codec    = Codecs.GetCodec(attribute.Codec);

                if (!autoIndex && attribute.Index < 0)
                {
                    throw new ArgumentException("A POF Index must be specified for the property "
                                                + type.Name + "#" + propName + " by specifying "
                                                + "within the annotation or enabling auto indexing");
                }

                builder.AddAttribute(
                    builder.NewAttribute()
                    .SetName(mangled)
                    .SetCodec(codec)
                    .SetInvocationStrategy(new IS.PropertyInvcationStrategy <TB>(prop))
                    .SetIndex(attribute.Index).Build());

                // field level annotations take precedence over accessor annotations
                fieldsExcluded.Add(mangled);
            }

            // get field level information
            FieldInfo[] fields = type.GetFields(bindings);

            for (int i = 0; i < fields.Length; ++i)
            {
                FieldInfo        field     = fields[i];
                PortableProperty attribute = Attribute.GetCustomAttribute(field, typeof(PortableProperty)) as PortableProperty;
                if (attribute == null)
                {
                    continue;
                }

                string fieldName = field.Name;
                string mangled   = NameManglers.FIELD_MANGLER.Mangle(fieldName);
                ICodec codec     = Codecs.GetCodec(attribute.Codec);

                if (!autoIndex && attribute.Index < 0)
                {
                    throw new ArgumentException("A POF Index must be specified for the property "
                                                + type.Name + "#" + fieldName + " by specifying "
                                                + "within the annotation or enabling auto indexing");
                }

                builder.AddAttribute(
                    builder.NewAttribute()
                    .SetName(mangled)
                    .SetCodec(codec)
                    .SetInvocationStrategy(new IS.FieldInvcationStrategy <TB>(field))
                    .SetIndex(attribute.Index).Build());

                // field level annotations take precedence over accessor annotations
                fieldsExcluded.Add(mangled);
            }

            // get method level information
            MethodInfo[] methods = type.GetMethods(bindings);
            for (int i = 0; i < methods.Length; ++i)
            {
                MethodInfo       method    = methods[i];
                PortableProperty attribute = Attribute.GetCustomAttribute(method, typeof(PortableProperty)) as PortableProperty;
                if (attribute == null)
                {
                    continue;
                }

                string methodName = method.Name;
                if (methodName.StartsWith("Get") || methodName.StartsWith("Set") ||
                    methodName.StartsWith("Is"))
                {
                    string mangled = NameManglers.METHOD_MANGLER.Mangle(methodName);
                    if (fieldsExcluded.Contains(mangled))
                    {
                        continue;
                    }

                    ICodec codec = Codecs.GetCodec(attribute.Codec);
                    if (!autoIndex && attribute.Index < 0)
                    {
                        throw new ArgumentException("A POF Index must be specified for the method "
                                                    + type.Name + "#" + methodName + " by specifying "
                                                    + "within the annotation or enabling auto indexing");
                    }

                    builder.AddAttribute(
                        builder.NewAttribute()
                        .SetName(mangled)
                        .SetCodec(codec)
                        .SetInvocationStrategy(new IS.MethodInvocationStrategy <TB>(method))
                        .SetIndex(attribute.Index).Build());

                    // in the case where both accessors (getters and setters) are
                    // annotated we only use the values in the first annotation we
                    // come stumble across
                    fieldsExcluded.Add(mangled);
                }
            }
        }