public static function factory($class, $property = null)
    {
        if (is_object($class))
            $class = get_class($class);
        $class = (string)$class;
        if (!isset(self::$properties[$class])) {
            $classReflection = new \ReflectionClass($class);
            $properties = $classReflection->getProperties();
            self::$properties[$class] = array();
            foreach ($properties as $propertyReflection) {
                if ($propertyReflection->class != $class) {
                    self::$properties[$class][$propertyReflection->name] = self::factory($propertyReflection->class, $propertyReflection->name);
                } else {
                    self::$properties[$class][$propertyReflection->name] = new self($propertyReflection->class, $propertyReflection->name);
                    self::$properties[$class][$propertyReflection->name]->setAccessible(true);
                }
            }
        }
        if (isset($property)) {
            if (!isset(self::$properties[$class][$property])) {
                self::$properties[$class][$property] = new self($class, $property);
                self::$properties[$class][$property]->setAccessible(true);
            }
            return self::$properties[$class][$property];
        } else
            return array_values(self::$properties[$class]);
    }