// Path: retired/regions/src/main/java/org/javamoney/regions/Region.java
// public interface Region {
// 
// 	/**
// 	 * Get the region's type.
// 	 * 
// 	 * @return the region's type, never {@code null}.
// 	 */
// 	public RegionType getRegionType();
// 
// 	/**
// 	 * Access the region's code. The code is unique in combination with the
// 	 * region type.
// 	 * 
// 	 * @return the region's type, never {@code null}.
// 	 */
// 	public String getRegionCode();
// 
// 	/**
// 	 * Get the region's numeric code. If not defined -1 is returned.
// 	 * 
// 	 * @return the numeric region code, or {@code -1}.
// 	 */
// 	public int getNumericRegionCode();
// 
// 	/**
// 	 * Return the time zones valid for this region (in the long form, e.g.
// 	 * Europe/Berlin). If the region has subregions, by default, the timezones
// 	 * returned should be the transitive closure of all timezones of all child
// 	 * regions. Nevertheless there might be use cases were the child regions
// 	 * must not transitively define the parents timezones, so transitivity is
// 	 * not enforced by this JSR.<br/>
// 	 * Additionally all ids returned should be known by {@link java.util.TimeZone}.
// 	 * 
// 	 * @return the timezone ids of this region, never {@code null}.
// 	 */
// 	public Collection<String> getTimezoneIds();
// 
// 	/**
// 	 * Return according {@link java.util.Locale}, if possible.
// 	 * 
// 	 * @return the corresponding {@link java.util.Locale} for that {@link org.javamoney.regions.Region}, may
// 	 *         also return {@code null}.
// 	 */
// 	public Locale getLocale();
// 
// }
// 
// Path: retired/regions/src/main/java/org/javamoney/regions/RegionTreeNode.java
// public interface RegionTreeNode {
// 
// 	/**
// 	 * Get the corresponding region.
// 	 * 
// 	 * @return the region, never {@code null}.
// 	 */
// 	public Region getRegion();
// 
// 	/**
// 	 * Get the direct parent region of this region.
// 	 * 
// 	 * @return the parent region, or {@code null}, if this region has no parent
// 	 *         (is a root region).
// 	 */
// 	public RegionTreeNode getParent();
// 
// 	/**
// 	 * Access all direct child regions.
// 	 * 
// 	 * @return all direct child regions, never {@code null}.
// 	 */
// 	public Collection<RegionTreeNode> getChildren();
// 
// 	/**
// 	 * Determines if the given region is contained within this region tree.
// 	 * 
// 	 * @param region
// 	 *            the region being looked up, null hereby is never contained.
// 	 * @return {@code true} if the given region is a direct or indirect child of
// 	 *         this region instance.
// 	 */
// 	public boolean contains(Region region);
// 
// 	/**
// 	 * Select the parent region with the given type. This method will navigate
// 	 * up the region tree and select the first parent encountered that has the
// 	 * given region type.
// 	 * 
// 	 * @param predicate
// 	 *            the selecting filter, {@code null} will return the direct
// 	 *            parent, if any.
// 	 * @return the region found, or {@code null}.
// 	 */
// 	public RegionTreeNode selectParent(MonetaryPredicate<Region> predicate);
// 
// 	/**
// 	 * Select a collection of regions selected by the given filter.
// 	 * 
// 	 * @param predicate
// 	 *            the region selector, {@code null} will return all regions.
// 	 * @return the regions selected.
// 	 */
// 	public Collection<RegionTreeNode> select(MonetaryPredicate<Region> predicate);
// 
// 	/**
// 	 * Access a {@link Region} using the region path, which allows access of a
// 	 * {@link Region} from the tree, e.g. {@code WORLD/EUROPE/GERMANY} or
// 	 * {@code STANDARDS/ISO/GER}.
// 	 * 
// 	 * @param path
// 	 *            the path to be accessed, not {@code null}.
// 	 * @return the {@link Region} found, or {@code null}.
// 	 */
// 	public RegionTreeNode getRegionTree(String path);
// 
// }


import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.javamoney.regions.Region;
import org.javamoney.regions.RegionTreeNode;
/*
 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE
 * CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT.
 * PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY. BY
 * DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF THE
 * AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE"
 * BUTTON AT THE BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency
 * API ("Specification") Copyright (c) 2012-2013, Credit Suisse All rights
 * reserved.
 */
package org.javamoney.regions.spi;



/**
 * {@link Region}s can be used to segregate or access artifacts (e.g.
 * CurrencyUnits) either based on geographical, or commercial aspects (e.g.
 * legal units). This implementation provides a class with an according
 * {@link org.javamoney.regions.spi.BuildableRegionNode.Builder} for creation.
 * 
 * @see <a href="http://unstats.un.org/unsd/methods/m49/m49regin.htm">UN M.49:
 *      UN Statistics Division Country or area & region codes</a>
 * 
 * @author Anatole Tresch
 */
public class BuildableRegionNode extends AbstractRegionNode implements
		RegionTreeNode, Serializable,
		Comparable<RegionTreeNode> {

	/**
	 * serialID.
	 */
	private static final long serialVersionUID = -8957470024522944264L;

	/**
	 * Creates a region. Regions should only be accessed using the accessor
	 * method {@link Monetary#getExtension(Class)}, passing
	 * {@link RegionProvider} as type.
	 * 
	 * @param id
	 *            the region's id, not null.
	 * @param type
	 *            the region's type, not null.
	 */
// Path: retired/regions/src/main/java/org/javamoney/regions/Region.java
// public interface Region {
// 
// 	/**
// 	 * Get the region's type.
// 	 * 
// 	 * @return the region's type, never {@code null}.
// 	 */
// 	public RegionType getRegionType();
// 
// 	/**
// 	 * Access the region's code. The code is unique in combination with the
// 	 * region type.
// 	 * 
// 	 * @return the region's type, never {@code null}.
// 	 */
// 	public String getRegionCode();
// 
// 	/**
// 	 * Get the region's numeric code. If not defined -1 is returned.
// 	 * 
// 	 * @return the numeric region code, or {@code -1}.
// 	 */
// 	public int getNumericRegionCode();
// 
// 	/**
// 	 * Return the time zones valid for this region (in the long form, e.g.
// 	 * Europe/Berlin). If the region has subregions, by default, the timezones
// 	 * returned should be the transitive closure of all timezones of all child
// 	 * regions. Nevertheless there might be use cases were the child regions
// 	 * must not transitively define the parents timezones, so transitivity is
// 	 * not enforced by this JSR.<br/>
// 	 * Additionally all ids returned should be known by {@link java.util.TimeZone}.
// 	 * 
// 	 * @return the timezone ids of this region, never {@code null}.
// 	 */
// 	public Collection<String> getTimezoneIds();
// 
// 	/**
// 	 * Return according {@link java.util.Locale}, if possible.
// 	 * 
// 	 * @return the corresponding {@link java.util.Locale} for that {@link org.javamoney.regions.Region}, may
// 	 *         also return {@code null}.
// 	 */
// 	public Locale getLocale();
// 
// }
// 
// Path: retired/regions/src/main/java/org/javamoney/regions/RegionTreeNode.java
// public interface RegionTreeNode {
// 
// 	/**
// 	 * Get the corresponding region.
// 	 * 
// 	 * @return the region, never {@code null}.
// 	 */
// 	public Region getRegion();
// 
// 	/**
// 	 * Get the direct parent region of this region.
// 	 * 
// 	 * @return the parent region, or {@code null}, if this region has no parent
// 	 *         (is a root region).
// 	 */
// 	public RegionTreeNode getParent();
// 
// 	/**
// 	 * Access all direct child regions.
// 	 * 
// 	 * @return all direct child regions, never {@code null}.
// 	 */
// 	public Collection<RegionTreeNode> getChildren();
// 
// 	/**
// 	 * Determines if the given region is contained within this region tree.
// 	 * 
// 	 * @param region
// 	 *            the region being looked up, null hereby is never contained.
// 	 * @return {@code true} if the given region is a direct or indirect child of
// 	 *         this region instance.
// 	 */
// 	public boolean contains(Region region);
// 
// 	/**
// 	 * Select the parent region with the given type. This method will navigate
// 	 * up the region tree and select the first parent encountered that has the
// 	 * given region type.
// 	 * 
// 	 * @param predicate
// 	 *            the selecting filter, {@code null} will return the direct
// 	 *            parent, if any.
// 	 * @return the region found, or {@code null}.
// 	 */
// 	public RegionTreeNode selectParent(MonetaryPredicate<Region> predicate);
// 
// 	/**
// 	 * Select a collection of regions selected by the given filter.
// 	 * 
// 	 * @param predicate
// 	 *            the region selector, {@code null} will return all regions.
// 	 * @return the regions selected.
// 	 */
// 	public Collection<RegionTreeNode> select(MonetaryPredicate<Region> predicate);
// 
// 	/**
// 	 * Access a {@link Region} using the region path, which allows access of a
// 	 * {@link Region} from the tree, e.g. {@code WORLD/EUROPE/GERMANY} or
// 	 * {@code STANDARDS/ISO/GER}.
// 	 * 
// 	 * @param path
// 	 *            the path to be accessed, not {@code null}.
// 	 * @return the {@link Region} found, or {@code null}.
// 	 */
// 	public RegionTreeNode getRegionTree(String path);
// 
// }


// Path: retired/regions/src/main/java/org/javamoney/regions/spi/BuildableRegionNode.java
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.javamoney.regions.Region;
import org.javamoney.regions.RegionTreeNode;

/*
 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE
 * CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT.
 * PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY. BY
 * DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF THE
 * AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE"
 * BUTTON AT THE BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency
 * API ("Specification") Copyright (c) 2012-2013, Credit Suisse All rights
 * reserved.
 */
package org.javamoney.regions.spi;



/**
 * {@link Region}s can be used to segregate or access artifacts (e.g.
 * CurrencyUnits) either based on geographical, or commercial aspects (e.g.
 * legal units). This implementation provides a class with an according
 * {@link org.javamoney.regions.spi.BuildableRegionNode.Builder} for creation.
 * 
 * @see <a href="http://unstats.un.org/unsd/methods/m49/m49regin.htm">UN M.49:
 *      UN Statistics Division Country or area & region codes</a>
 * 
 * @author Anatole Tresch
 */
public class BuildableRegionNode extends AbstractRegionNode implements
		RegionTreeNode, Serializable,
		Comparable<RegionTreeNode> {

	/**
	 * serialID.
	 */
	private static final long serialVersionUID = -8957470024522944264L;

	/**
	 * Creates a region. Regions should only be accessed using the accessor
	 * method {@link Monetary#getExtension(Class)}, passing
	 * {@link RegionProvider} as type.
	 * 
	 * @param id
	 *            the region's id, not null.
	 * @param type
	 *            the region's type, not null.
	 */
	public BuildableRegionNode(Region region) {