private function parseProperty($property_node, SwatUIObject $object)
    {
        $class_properties = get_class_vars(get_class($object));

        // name is required in the schema
        $name = trim($property_node->getAttribute('name'));
        $value = $property_node->nodeValue;

        $array_property = false;

        if (preg_match('/^(.*)\[(.*)\]$/u', $name, $regs)) {
            $array_property = true;
            $name = $regs[1];
            $array_key = $regs[2] == '' ? null : $regs[2];
        }

        if (!array_key_exists($name, $class_properties)) {
            $class_name = get_class($object);
            throw new SwatInvalidPropertyException(
                "Property '{$name}' does not exist in class '{$class_name}' " .
                    'but is used in SwatML.',
                0,
                $object,
                $name
            );
        }

        // translatable is optional in the schema
        if ($property_node->hasAttribute('translatable')) {
            $translatable =
                $property_node->getAttribute('translatable') == 'yes';
        } else {
            $translatable = false;
        }

        // type is optional in the schema
        if ($property_node->hasAttribute('type')) {
            $type = $property_node->getAttribute('type');
        } else {
            $type = 'implicit-string';
        }

        $parsed_value = $this->parseValue(
            $name,
            $value,
            $type,
            $translatable,
            $object
        );

        if ($array_property) {
            if ($parsed_value instanceof SwatCellRendererMapping) {
                // it was a type=data property,
                // so the parsed value is a mapping object
                $parsed_value->is_array = true;
                $parsed_value->array_key = $array_key;
            } else {
                if (!is_array($object->$name)) {
                    $object->$name = array();
                }

                $array_ref = &$object->$name;

                if ($array_key === null) {
                    $array_ref[] = $parsed_value;
                } else {
                    $array_ref[$array_key] = $parsed_value;
                }
            }
        } else {
            $object->$name = $parsed_value;
        }
    }