public function parse($data, $chunkSize = 1024)
    {
        //Ensure that the $data var is of the right type
        if (!is_string($data) && (!is_resource($data) || get_resource_type($data) !== 'stream')) {
            throw new Exception('Data must be a string or a stream resource');
        }

        //Ensure $chunkSize is the right type
        if (!is_int($chunkSize)) {
            throw new Exception('Chunk size must be an integer');
        }

        //Initialise the object
        $this->init();

        //Create the parser and set the parsing flag
        $this->parse = TRUE;
        $parser      = xml_parser_create();

        //Set the parser up, ready to stream through the XML
        xml_set_object($parser, $this);

        //Set up the protected methods _start and _end to deal with the start
        //and end tags respectively
        xml_set_element_handler($parser, 'start', 'end');

        //Set up the _addCdata method to parse any CDATA tags
        xml_set_character_data_handler($parser, 'addCdata');

        //For general purpose data, use the _addData method
        xml_set_default_handler($parser, 'addData');

        //If the data is a resource then loop through it, otherwise just parse
        //the string
        if (is_resource($data)) {
            //Not all resources support fseek. For those that don't, suppress
            // /the error
            @fseek($data, 0);

            while ($this->parse && $chunk = fread($data, $chunkSize)) {
                $this->parseString($parser, $chunk, feof($data));
            }
        } else {
            $this->parseString($parser, $data, TRUE);
        }

        //Free up the parser
        xml_parser_free($parser);

        return $this;
    }