/*
 *  Copyright 2001-present Stephen Colebourne
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.joda.beans.sample;

import java.io.Serializable;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.joda.beans.Bean;
import org.joda.beans.ImmutableBean;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaBean;
import org.joda.beans.MetaProperty;
import org.joda.beans.gen.BeanDefinition;
import org.joda.beans.gen.PropertyDefinition;
import org.joda.beans.impl.direct.DirectFieldsBeanBuilder;
import org.joda.beans.impl.direct.DirectMetaBean;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import org.joda.collect.grid.Grid;
import org.joda.collect.grid.ImmutableGrid;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;

/**
 * Mock address JavaBean, used for testing.
 * 
 * @author Stephen Colebourne
 */
@BeanDefinition(constructorScope = "private")
public final class ImmAddress implements ImmutableBean, Serializable {

    /**
     * The number.
     * This will be the flat, house number or house name.
     */
    @PropertyDefinition
    private final int number;
    /**
     * The street.
     */
    @PropertyDefinition(validate = "notNull")
    private final String street;
    /**
     * The city.
     */
    @PropertyDefinition(validate = "notNull")
    private final String city;
    /**
     * The abstract number.
     */
    @PropertyDefinition
    private final Number abstractNumber;
    /**
     * The extra data.
     */
    @PropertyDefinition
    private final byte[] data;
    /**
     * The 2D array.
     */
    @PropertyDefinition
    private final String[][] array2d;
    /**
     * The owner.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmPerson owner;
    /**
     * The object field.
     */
    @PropertyDefinition
    private final Object object1;
    /**
     * The object field.
     */
    @PropertyDefinition
    private final Object object2;
    /**
     * The risk field.
     */
    @PropertyDefinition
    private final Risk risk;
    /**
     * The risk level field, testing an {@code Enum}.
     */
    @PropertyDefinition
    private final RiskLevel riskLevel;
    /**
     * The risk levels field, testing {@code EnumSet}.
     */
    @PropertyDefinition
    private final EnumSet<RiskLevel> riskLevels;
    /**
     * The serializable field.
     */
    @PropertyDefinition
    private final Serializable serializable;
    /**
     * The object in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<String, Object> objectInMap;
    /**
     * The list in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<String, List<String>> listInMap;
    /**
     * The list in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<String, List<Integer>> listNumericInMap;
    /**
     * The list in list in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<String, List<List<Integer>>> listInListInMap;
    /**
     * The object list in list in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<String, List<List<Object>>> objectListInListInMap;
    /**
     * The map in map field.
     */
    @PropertyDefinition(validate = "notNull")
    private final ImmutableMap<ImmPerson, Map<String, ImmPerson>> mapInMap;
    /**
     * The simple table.
     */
    @PropertyDefinition
    private final ImmutableTable<Integer, Integer, String> simpleTable;
    /**
     * The compound table.
     */
    @PropertyDefinition
    private final ImmutableTable<Integer, Integer, ImmPerson> compoundTable;
    /**
     * The grid.
     */
    @PropertyDefinition
    private final ImmutableGrid<ImmPerson> sparseGrid;
    /**
     * The grid.
     */
    @PropertyDefinition
    @SimpleAnnotation(first = "a",
            second = "b",
            third = "c")
    private final ImmutableGrid<ImmPerson> denseGrid;
    /**
     * The bean key and bean value field.
     */
    @PropertyDefinition(validate = "notNull")
    // comment is ignored
    private final ImmutableMap<ImmPerson, ImmAddress> beanBeanMap;
    /**
     * The array.
     */
    @PropertyDefinition
    private final double[] doubleVector;
    /**
     * The matrix.
     */
    @PropertyDefinition

    private final double[][] matrix;
    // blank line above is ignored

    //------------------------- AUTOGENERATED START -------------------------
    /**
     * The meta-bean for {@code ImmAddress}.
     * @return the meta-bean, not null
     */
    public static ImmAddress.Meta meta() {
        return ImmAddress.Meta.INSTANCE;
    }

    static {
        MetaBean.register(ImmAddress.Meta.INSTANCE);
    }

    /**
     * The serialization version id.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Returns a builder used to create an instance of the bean.
     * @return the builder, not null
     */
    public static ImmAddress.Builder builder() {
        return new ImmAddress.Builder();
    }

    private ImmAddress(
            int number,
            String street,
            String city,
            Number abstractNumber,
            byte[] data,
            String[][] array2d,
            ImmPerson owner,
            Object object1,
            Object object2,
            Risk risk,
            RiskLevel riskLevel,
            Set<RiskLevel> riskLevels,
            Serializable serializable,
            Map<String, Object> objectInMap,
            Map<String, List<String>> listInMap,
            Map<String, List<Integer>> listNumericInMap,
            Map<String, List<List<Integer>>> listInListInMap,
            Map<String, List<List<Object>>> objectListInListInMap,
            Map<ImmPerson, Map<String, ImmPerson>> mapInMap,
            Table<Integer, Integer, String> simpleTable,
            Table<Integer, Integer, ImmPerson> compoundTable,
            Grid<ImmPerson> sparseGrid,
            Grid<ImmPerson> denseGrid,
            Map<ImmPerson, ImmAddress> beanBeanMap,
            double[] doubleVector,
            double[][] matrix) {
        JodaBeanUtils.notNull(street, "street");
        JodaBeanUtils.notNull(city, "city");
        JodaBeanUtils.notNull(owner, "owner");
        JodaBeanUtils.notNull(objectInMap, "objectInMap");
        JodaBeanUtils.notNull(listInMap, "listInMap");
        JodaBeanUtils.notNull(listNumericInMap, "listNumericInMap");
        JodaBeanUtils.notNull(listInListInMap, "listInListInMap");
        JodaBeanUtils.notNull(objectListInListInMap, "objectListInListInMap");
        JodaBeanUtils.notNull(mapInMap, "mapInMap");
        JodaBeanUtils.notNull(beanBeanMap, "beanBeanMap");
        this.number = number;
        this.street = street;
        this.city = city;
        this.abstractNumber = abstractNumber;
        this.data = (data != null ? data.clone() : null);
        this.array2d = (String[][]) JodaBeanUtils.cloneArray(array2d);
        this.owner = owner;
        this.object1 = object1;
        this.object2 = object2;
        this.risk = risk;
        this.riskLevel = riskLevel;
        this.riskLevels = (riskLevels != null ? EnumSet.copyOf(riskLevels) : null);
        this.serializable = serializable;
        this.objectInMap = ImmutableMap.copyOf(objectInMap);
        this.listInMap = ImmutableMap.copyOf(listInMap);
        this.listNumericInMap = ImmutableMap.copyOf(listNumericInMap);
        this.listInListInMap = ImmutableMap.copyOf(listInListInMap);
        this.objectListInListInMap = ImmutableMap.copyOf(objectListInListInMap);
        this.mapInMap = ImmutableMap.copyOf(mapInMap);
        this.simpleTable = (simpleTable != null ? ImmutableTable.copyOf(simpleTable) : null);
        this.compoundTable = (compoundTable != null ? ImmutableTable.copyOf(compoundTable) : null);
        this.sparseGrid = (sparseGrid != null ? ImmutableGrid.copyOf(sparseGrid) : null);
        this.denseGrid = (denseGrid != null ? ImmutableGrid.copyOf(denseGrid) : null);
        this.beanBeanMap = ImmutableMap.copyOf(beanBeanMap);
        this.doubleVector = (doubleVector != null ? doubleVector.clone() : null);
        this.matrix = (double[][]) JodaBeanUtils.cloneArray(matrix);
    }

    @Override
    public ImmAddress.Meta metaBean() {
        return ImmAddress.Meta.INSTANCE;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the number.
     * This will be the flat, house number or house name.
     * @return the value of the property
     */
    public int getNumber() {
        return number;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the street.
     * @return the value of the property, not null
     */
    public String getStreet() {
        return street;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the city.
     * @return the value of the property, not null
     */
    public String getCity() {
        return city;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the abstract number.
     * @return the value of the property
     */
    public Number getAbstractNumber() {
        return abstractNumber;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the extra data.
     * @return the value of the property
     */
    public byte[] getData() {
        return (data != null ? data.clone() : null);
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the 2D array.
     * @return the value of the property
     */
    public String[][] getArray2d() {
        return (String[][]) JodaBeanUtils.cloneArray(array2d);
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the owner.
     * @return the value of the property, not null
     */
    public ImmPerson getOwner() {
        return owner;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the object field.
     * @return the value of the property
     */
    public Object getObject1() {
        return object1;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the object field.
     * @return the value of the property
     */
    public Object getObject2() {
        return object2;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the risk field.
     * @return the value of the property
     */
    public Risk getRisk() {
        return risk;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the risk level field, testing an {@code Enum}.
     * @return the value of the property
     */
    public RiskLevel getRiskLevel() {
        return riskLevel;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the risk levels field, testing {@code EnumSet}.
     * @return the value of the property
     */
    public EnumSet<RiskLevel> getRiskLevels() {
        return riskLevels;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the serializable field.
     * @return the value of the property
     */
    public Serializable getSerializable() {
        return serializable;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the object in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<String, Object> getObjectInMap() {
        return objectInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the list in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<String, List<String>> getListInMap() {
        return listInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the list in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<String, List<Integer>> getListNumericInMap() {
        return listNumericInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the list in list in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<String, List<List<Integer>>> getListInListInMap() {
        return listInListInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the object list in list in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<String, List<List<Object>>> getObjectListInListInMap() {
        return objectListInListInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the map in map field.
     * @return the value of the property, not null
     */
    public ImmutableMap<ImmPerson, Map<String, ImmPerson>> getMapInMap() {
        return mapInMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the simple table.
     * @return the value of the property
     */
    public ImmutableTable<Integer, Integer, String> getSimpleTable() {
        return simpleTable;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the compound table.
     * @return the value of the property
     */
    public ImmutableTable<Integer, Integer, ImmPerson> getCompoundTable() {
        return compoundTable;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the grid.
     * @return the value of the property
     */
    public ImmutableGrid<ImmPerson> getSparseGrid() {
        return sparseGrid;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the grid.
     * @return the value of the property
     */
    public ImmutableGrid<ImmPerson> getDenseGrid() {
        return denseGrid;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the bean key and bean value field.
     * @return the value of the property, not null
     */
    public ImmutableMap<ImmPerson, ImmAddress> getBeanBeanMap() {
        return beanBeanMap;
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the array.
     * @return the value of the property
     */
    public double[] getDoubleVector() {
        return (doubleVector != null ? doubleVector.clone() : null);
    }

    //-----------------------------------------------------------------------
    /**
     * Gets the matrix.
     * @return the value of the property
     */
    public double[][] getMatrix() {
        return (double[][]) JodaBeanUtils.cloneArray(matrix);
    }

    //-----------------------------------------------------------------------
    /**
     * Returns a builder that allows this bean to be mutated.
     * @return the mutable builder, not null
     */
    public Builder toBuilder() {
        return new Builder(this);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj.getClass() == this.getClass()) {
            ImmAddress other = (ImmAddress) obj;
            return (this.number == other.number) &&
                    JodaBeanUtils.equal(this.street, other.street) &&
                    JodaBeanUtils.equal(this.city, other.city) &&
                    JodaBeanUtils.equal(this.abstractNumber, other.abstractNumber) &&
                    JodaBeanUtils.equal(this.data, other.data) &&
                    JodaBeanUtils.equal(this.array2d, other.array2d) &&
                    JodaBeanUtils.equal(this.owner, other.owner) &&
                    JodaBeanUtils.equal(this.object1, other.object1) &&
                    JodaBeanUtils.equal(this.object2, other.object2) &&
                    JodaBeanUtils.equal(this.risk, other.risk) &&
                    JodaBeanUtils.equal(this.riskLevel, other.riskLevel) &&
                    JodaBeanUtils.equal(this.riskLevels, other.riskLevels) &&
                    JodaBeanUtils.equal(this.serializable, other.serializable) &&
                    JodaBeanUtils.equal(this.objectInMap, other.objectInMap) &&
                    JodaBeanUtils.equal(this.listInMap, other.listInMap) &&
                    JodaBeanUtils.equal(this.listNumericInMap, other.listNumericInMap) &&
                    JodaBeanUtils.equal(this.listInListInMap, other.listInListInMap) &&
                    JodaBeanUtils.equal(this.objectListInListInMap, other.objectListInListInMap) &&
                    JodaBeanUtils.equal(this.mapInMap, other.mapInMap) &&
                    JodaBeanUtils.equal(this.simpleTable, other.simpleTable) &&
                    JodaBeanUtils.equal(this.compoundTable, other.compoundTable) &&
                    JodaBeanUtils.equal(this.sparseGrid, other.sparseGrid) &&
                    JodaBeanUtils.equal(this.denseGrid, other.denseGrid) &&
                    JodaBeanUtils.equal(this.beanBeanMap, other.beanBeanMap) &&
                    JodaBeanUtils.equal(this.doubleVector, other.doubleVector) &&
                    JodaBeanUtils.equal(this.matrix, other.matrix);
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = getClass().hashCode();
        hash = hash * 31 + JodaBeanUtils.hashCode(number);
        hash = hash * 31 + JodaBeanUtils.hashCode(street);
        hash = hash * 31 + JodaBeanUtils.hashCode(city);
        hash = hash * 31 + JodaBeanUtils.hashCode(abstractNumber);
        hash = hash * 31 + JodaBeanUtils.hashCode(data);
        hash = hash * 31 + JodaBeanUtils.hashCode(array2d);
        hash = hash * 31 + JodaBeanUtils.hashCode(owner);
        hash = hash * 31 + JodaBeanUtils.hashCode(object1);
        hash = hash * 31 + JodaBeanUtils.hashCode(object2);
        hash = hash * 31 + JodaBeanUtils.hashCode(risk);
        hash = hash * 31 + JodaBeanUtils.hashCode(riskLevel);
        hash = hash * 31 + JodaBeanUtils.hashCode(riskLevels);
        hash = hash * 31 + JodaBeanUtils.hashCode(serializable);
        hash = hash * 31 + JodaBeanUtils.hashCode(objectInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(listInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(listNumericInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(listInListInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(objectListInListInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(mapInMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(simpleTable);
        hash = hash * 31 + JodaBeanUtils.hashCode(compoundTable);
        hash = hash * 31 + JodaBeanUtils.hashCode(sparseGrid);
        hash = hash * 31 + JodaBeanUtils.hashCode(denseGrid);
        hash = hash * 31 + JodaBeanUtils.hashCode(beanBeanMap);
        hash = hash * 31 + JodaBeanUtils.hashCode(doubleVector);
        hash = hash * 31 + JodaBeanUtils.hashCode(matrix);
        return hash;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder(864);
        buf.append("ImmAddress{");
        buf.append("number").append('=').append(JodaBeanUtils.toString(number)).append(',').append(' ');
        buf.append("street").append('=').append(JodaBeanUtils.toString(street)).append(',').append(' ');
        buf.append("city").append('=').append(JodaBeanUtils.toString(city)).append(',').append(' ');
        buf.append("abstractNumber").append('=').append(JodaBeanUtils.toString(abstractNumber)).append(',').append(' ');
        buf.append("data").append('=').append(JodaBeanUtils.toString(data)).append(',').append(' ');
        buf.append("array2d").append('=').append(JodaBeanUtils.toString(array2d)).append(',').append(' ');
        buf.append("owner").append('=').append(JodaBeanUtils.toString(owner)).append(',').append(' ');
        buf.append("object1").append('=').append(JodaBeanUtils.toString(object1)).append(',').append(' ');
        buf.append("object2").append('=').append(JodaBeanUtils.toString(object2)).append(',').append(' ');
        buf.append("risk").append('=').append(JodaBeanUtils.toString(risk)).append(',').append(' ');
        buf.append("riskLevel").append('=').append(JodaBeanUtils.toString(riskLevel)).append(',').append(' ');
        buf.append("riskLevels").append('=').append(JodaBeanUtils.toString(riskLevels)).append(',').append(' ');
        buf.append("serializable").append('=').append(JodaBeanUtils.toString(serializable)).append(',').append(' ');
        buf.append("objectInMap").append('=').append(JodaBeanUtils.toString(objectInMap)).append(',').append(' ');
        buf.append("listInMap").append('=').append(JodaBeanUtils.toString(listInMap)).append(',').append(' ');
        buf.append("listNumericInMap").append('=').append(JodaBeanUtils.toString(listNumericInMap)).append(',').append(' ');
        buf.append("listInListInMap").append('=').append(JodaBeanUtils.toString(listInListInMap)).append(',').append(' ');
        buf.append("objectListInListInMap").append('=').append(JodaBeanUtils.toString(objectListInListInMap)).append(',').append(' ');
        buf.append("mapInMap").append('=').append(JodaBeanUtils.toString(mapInMap)).append(',').append(' ');
        buf.append("simpleTable").append('=').append(JodaBeanUtils.toString(simpleTable)).append(',').append(' ');
        buf.append("compoundTable").append('=').append(JodaBeanUtils.toString(compoundTable)).append(',').append(' ');
        buf.append("sparseGrid").append('=').append(JodaBeanUtils.toString(sparseGrid)).append(',').append(' ');
        buf.append("denseGrid").append('=').append(JodaBeanUtils.toString(denseGrid)).append(',').append(' ');
        buf.append("beanBeanMap").append('=').append(JodaBeanUtils.toString(beanBeanMap)).append(',').append(' ');
        buf.append("doubleVector").append('=').append(JodaBeanUtils.toString(doubleVector)).append(',').append(' ');
        buf.append("matrix").append('=').append(JodaBeanUtils.toString(matrix));
        buf.append('}');
        return buf.toString();
    }

    //-----------------------------------------------------------------------
    /**
     * The meta-bean for {@code ImmAddress}.
     */
    public static final class Meta extends DirectMetaBean {
        /**
         * The singleton instance of the meta-bean.
         */
        static final Meta INSTANCE = new Meta();

        /**
         * The meta-property for the {@code number} property.
         */
        private final MetaProperty<Integer> number = DirectMetaProperty.ofImmutable(
                this, "number", ImmAddress.class, Integer.TYPE);
        /**
         * The meta-property for the {@code street} property.
         */
        private final MetaProperty<String> street = DirectMetaProperty.ofImmutable(
                this, "street", ImmAddress.class, String.class);
        /**
         * The meta-property for the {@code city} property.
         */
        private final MetaProperty<String> city = DirectMetaProperty.ofImmutable(
                this, "city", ImmAddress.class, String.class);
        /**
         * The meta-property for the {@code abstractNumber} property.
         */
        private final MetaProperty<Number> abstractNumber = DirectMetaProperty.ofImmutable(
                this, "abstractNumber", ImmAddress.class, Number.class);
        /**
         * The meta-property for the {@code data} property.
         */
        private final MetaProperty<byte[]> data = DirectMetaProperty.ofImmutable(
                this, "data", ImmAddress.class, byte[].class);
        /**
         * The meta-property for the {@code array2d} property.
         */
        private final MetaProperty<String[][]> array2d = DirectMetaProperty.ofImmutable(
                this, "array2d", ImmAddress.class, String[][].class);
        /**
         * The meta-property for the {@code owner} property.
         */
        private final MetaProperty<ImmPerson> owner = DirectMetaProperty.ofImmutable(
                this, "owner", ImmAddress.class, ImmPerson.class);
        /**
         * The meta-property for the {@code object1} property.
         */
        private final MetaProperty<Object> object1 = DirectMetaProperty.ofImmutable(
                this, "object1", ImmAddress.class, Object.class);
        /**
         * The meta-property for the {@code object2} property.
         */
        private final MetaProperty<Object> object2 = DirectMetaProperty.ofImmutable(
                this, "object2", ImmAddress.class, Object.class);
        /**
         * The meta-property for the {@code risk} property.
         */
        private final MetaProperty<Risk> risk = DirectMetaProperty.ofImmutable(
                this, "risk", ImmAddress.class, Risk.class);
        /**
         * The meta-property for the {@code riskLevel} property.
         */
        private final MetaProperty<RiskLevel> riskLevel = DirectMetaProperty.ofImmutable(
                this, "riskLevel", ImmAddress.class, RiskLevel.class);
        /**
         * The meta-property for the {@code riskLevels} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<EnumSet<RiskLevel>> riskLevels = DirectMetaProperty.ofImmutable(
                this, "riskLevels", ImmAddress.class, (Class) EnumSet.class);
        /**
         * The meta-property for the {@code serializable} property.
         */
        private final MetaProperty<Serializable> serializable = DirectMetaProperty.ofImmutable(
                this, "serializable", ImmAddress.class, Serializable.class);
        /**
         * The meta-property for the {@code objectInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<String, Object>> objectInMap = DirectMetaProperty.ofImmutable(
                this, "objectInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code listInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<String, List<String>>> listInMap = DirectMetaProperty.ofImmutable(
                this, "listInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code listNumericInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<String, List<Integer>>> listNumericInMap = DirectMetaProperty.ofImmutable(
                this, "listNumericInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code listInListInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<String, List<List<Integer>>>> listInListInMap = DirectMetaProperty.ofImmutable(
                this, "listInListInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code objectListInListInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<String, List<List<Object>>>> objectListInListInMap = DirectMetaProperty.ofImmutable(
                this, "objectListInListInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code mapInMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<ImmPerson, Map<String, ImmPerson>>> mapInMap = DirectMetaProperty.ofImmutable(
                this, "mapInMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code simpleTable} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableTable<Integer, Integer, String>> simpleTable = DirectMetaProperty.ofImmutable(
                this, "simpleTable", ImmAddress.class, (Class) ImmutableTable.class);
        /**
         * The meta-property for the {@code compoundTable} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableTable<Integer, Integer, ImmPerson>> compoundTable = DirectMetaProperty.ofImmutable(
                this, "compoundTable", ImmAddress.class, (Class) ImmutableTable.class);
        /**
         * The meta-property for the {@code sparseGrid} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableGrid<ImmPerson>> sparseGrid = DirectMetaProperty.ofImmutable(
                this, "sparseGrid", ImmAddress.class, (Class) ImmutableGrid.class);
        /**
         * The meta-property for the {@code denseGrid} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableGrid<ImmPerson>> denseGrid = DirectMetaProperty.ofImmutable(
                this, "denseGrid", ImmAddress.class, (Class) ImmutableGrid.class);
        /**
         * The meta-property for the {@code beanBeanMap} property.
         */
        @SuppressWarnings({"unchecked", "rawtypes" })
        private final MetaProperty<ImmutableMap<ImmPerson, ImmAddress>> beanBeanMap = DirectMetaProperty.ofImmutable(
                this, "beanBeanMap", ImmAddress.class, (Class) ImmutableMap.class);
        /**
         * The meta-property for the {@code doubleVector} property.
         */
        private final MetaProperty<double[]> doubleVector = DirectMetaProperty.ofImmutable(
                this, "doubleVector", ImmAddress.class, double[].class);
        /**
         * The meta-property for the {@code matrix} property.
         */
        private final MetaProperty<double[][]> matrix = DirectMetaProperty.ofImmutable(
                this, "matrix", ImmAddress.class, double[][].class);
        /**
         * The meta-properties.
         */
        private final Map<String, MetaProperty<?>> metaPropertyMap$ = new DirectMetaPropertyMap(
                this, null,
                "number",
                "street",
                "city",
                "abstractNumber",
                "data",
                "array2d",
                "owner",
                "object1",
                "object2",
                "risk",
                "riskLevel",
                "riskLevels",
                "serializable",
                "objectInMap",
                "listInMap",
                "listNumericInMap",
                "listInListInMap",
                "objectListInListInMap",
                "mapInMap",
                "simpleTable",
                "compoundTable",
                "sparseGrid",
                "denseGrid",
                "beanBeanMap",
                "doubleVector",
                "matrix");

        /**
         * Restricted constructor.
         */
        private Meta() {
        }

        @Override
        protected MetaProperty<?> metaPropertyGet(String propertyName) {
            switch (propertyName.hashCode()) {
                case -1034364087:  // number
                    return this.number;
                case -891990013:  // street
                    return this.street;
                case 3053931:  // city
                    return this.city;
                case 1986500107:  // abstractNumber
