docs: @SuppressWarnings("unchecked")
  	public boolean add(Object child)
  	{
  		if (child == null)
  		{
  			throw new IllegalArgumentException(Messages.getString("beans.67"));
  		}
  
  		BeanContextChild proxy = null;
  
  		synchronized (globalHierarchyLock)
  		{
  			// check existence
  			if (contains(child))
  			{
  				return false;
  			}
  
  			// check serializing state
  			if (serializing)
  			{
  				throw new IllegalStateException(Messages.getString("beans.68"));
  			}
  
  			// validate
  			boolean valid = validatePendingAdd(child);
  			if (!valid)
  			{
  				throw new IllegalStateException(Messages.getString("beans.69"));
  			}
  
  			// find the proxy, if there's one
  			if (child instanceof BeanContextProxy)
  			{
  				proxy = ((BeanContextProxy) child).getBeanContextProxy();
  				if (proxy == null)
  				{
  					throw new NullPointerException(Messages.getString("beans.6A"));
  				}
  			}
  			BeanContextChild beanContextChild = getChildBeanContextChild(child);
  
  			// add to children
  			BCSChild childBCSC = null, proxyBCSC = null;
  			synchronized (children)
  			{
  				childBCSC = createBCSChild(child, proxy);
  				children.put(child, childBCSC);
  				if (proxy != null)
  				{
  					proxyBCSC = createBCSChild(proxy, child);
  					children.put(proxy, proxyBCSC);
  				}
  			}
  
  			// set child's beanContext property
  			if (beanContextChild != null)
  			{
  				try
  				{
  					beanContextChild.setBeanContext(getBeanContextPeer());
  				}
  				catch (PropertyVetoException e)
  				{
  					synchronized (children)
  					{
  						children.remove(child);
  						if (proxy != null)
  						{
  							children.remove(proxy);
  						}
  					}
  					throw new IllegalStateException(Messages.getString("beans.6B"));
  				}
  				// ensure no duplicate listener
  				beanContextChild.removePropertyChangeListener("beanContext", nonSerPCL);
  				// listen to child's beanContext change
  				beanContextChild.addPropertyChangeListener("beanContext", nonSerPCL);
  			}
  
  			// trigger hook
  			synchronized (child)
  			{
  				addSerializable(childBCSC);
  				childJustAddedHook(child, childBCSC);
  			}
  			if (proxy != null)
  			{
  				synchronized (proxy)
  				{
  					addSerializable(proxyBCSC);
  					childJustAddedHook(proxy, proxyBCSC);
  				}
  			}
  		}
  
  		// notify listeners
  		fireChildrenAdded(new BeanContextMembershipEvent(getBeanContextPeer(), proxy == null ? new Object[] { child } : new Object[] { child, proxy }));
  		return true;
  	}