function recursive($arg,$func,$stack=NULL) {
		if ($stack) {
			foreach ($stack as $node)
				if ($arg===$node)
					return $arg;
		}
		else
			$stack=array();
		switch (gettype($arg)) {
			case 'object':
				if (method_exists('ReflectionClass','iscloneable')) {
					$ref=new ReflectionClass($arg);
					if ($ref->iscloneable()) {
						$arg=clone($arg);
						$cast=is_a($arg,'IteratorAggregate')?
							iterator_to_array($arg):get_object_vars($arg);
						foreach ($cast as $key=>$val)
							$arg->$key=$this->recursive(
								$val,$func,array_merge($stack,array($arg)));
					}
				}
				return $arg;
			case 'array':
				$copy=array();
				foreach ($arg as $key=>$val)
					$copy[$key]=$this->recursive($val,$func,
						array_merge($stack,array($arg)));
				return $copy;
		}
		return $func($arg);
	}