public Collection<ArbitraryAttributeModel> toModelCollection() {
        return new AbstractCollection<ArbitraryAttributeModel>() {

            @Override
            public void clear() {
                ArbitraryAttributeMap.this.clear();
            }

            @Override
            public boolean remove(Object o) {

                // The Collection view of an ArbitraryAttributeMap can contain
                // only ArbitraryAttributeModel objects
                if (!(o instanceof ArbitraryAttributeModel))
                    return false;

                // Remove only if key is actually present
                ArbitraryAttributeModel model = (ArbitraryAttributeModel) o;
                if (!ArbitraryAttributeMap.this.containsKey(model.getName()))
                    return false;

                // The attribute should be removed only if the value matches
                String currentValue = ArbitraryAttributeMap.this.get(model.getName());
                if (currentValue == null) {
                    if (model.getValue() != null)
                        return false;
                }
                else if (!currentValue.equals(model.getValue()))
                    return false;

                ArbitraryAttributeMap.this.remove(model.getName());
                return true;

            }

            @Override
            public boolean add(ArbitraryAttributeModel e) {

                String newValue = e.getValue();
                String oldValue = put(e.getName(), newValue);

                // If null value is being added, collection changed only if
                // old value was non-null
                if (newValue == null)
                    return oldValue != null;

                // Collection changed if value changed
                return !newValue.equals(oldValue);

            }

            @Override
            public boolean contains(Object o) {

                // The Collection view of an ArbitraryAttributeMap can contain
                // only ArbitraryAttributeModel objects
                if (!(o instanceof ArbitraryAttributeModel))
                    return false;

                // No need to check the value of the attribute if the attribute
                // is not even present
                ArbitraryAttributeModel model = (ArbitraryAttributeModel) o;
                String value = get(model.getName());
                if (value == null)
                    return false;

                // The name/value pair is present only if the value matches
                return value.equals(model.getValue());

            }

            @Override
            public Iterator<ArbitraryAttributeModel> iterator() {

                // Get iterator over all string name/value entries
                final Iterator<Map.Entry<String, String>> iterator = entrySet().iterator();

                // Dynamically translate each string name/value entry into a
                // corresponding attribute model object as iteration continues
                return new Iterator<ArbitraryAttributeModel>() {

                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }

                    @Override
                    public ArbitraryAttributeModel next() {
                        Map.Entry<String, String> entry = iterator.next();
                        return new ArbitraryAttributeModel(entry.getKey(),
                                entry.getValue());
                    }

                    @Override
                    public void remove() {
                        iterator.remove();
                    }

                };

            }

            @Override
            public int size() {
                return ArbitraryAttributeMap.this.size();
            }

        };
    }
Returns a collection of model objects which mirrors the contents of this
ArbitraryAttributeMap. Each name/value pair within the map is reflected
by a corresponding model object within the returned collection. Removing
a model object from the collection removes the corresponding name/value
pair from the map. Adding a new model object to the collection adds a
corresponding name/value pair to the map. Changes to a model object
within the collection are NOT reflected on the map, however.

@return
    A collection of model objects which mirrors the contents of this
    ArbitraryAttributeMap.
extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/base/ArbitraryAttributeMap.java