public Object clone() throws CloneNotSupportedException {
        BeanMap newMap = (BeanMap)super.clone();

        if(bean == null) {
            // no bean, just an empty bean map at the moment.  return a newly
            // cloned and empty bean map.
            return newMap;
        }

        Object newBean = null;            
        Class beanClass = bean.getClass(); // Cannot throw Exception
        try {
            newBean = beanClass.newInstance();
        } catch (Exception e) {
            // unable to instantiate
            CloneNotSupportedException cnse = new CloneNotSupportedException
                ("Unable to instantiate the underlying bean \"" +
                 beanClass.getName() + "\": " + e);
            BeanUtils.initCause(cnse, e);
            throw cnse;
        }
            
        try {
            newMap.setBean(newBean);
        } catch (Exception exception) {
            CloneNotSupportedException cnse = new CloneNotSupportedException
                ("Unable to set bean in the cloned bean map: " + 
                 exception);
            BeanUtils.initCause(cnse, exception);
            throw cnse;
        }
            
        try {
            // copy only properties that are readable and writable.  If its
            // not readable, we can't get the value from the old map.  If
            // its not writable, we can't write a value into the new map.
            Iterator readableKeys = readMethods.keySet().iterator();
            while(readableKeys.hasNext()) {
                Object key = readableKeys.next();
                if(getWriteMethod(key) != null) {
                    newMap.put(key, get(key));
                }
            }
        } catch (Exception exception) {
            CloneNotSupportedException cnse = new CloneNotSupportedException
                ("Unable to copy bean values to cloned bean map: " +
                 exception);
            BeanUtils.initCause(cnse, exception);
            throw cnse;
        }

        return newMap;
    }