public function establish() {

                // Check whether the socket is already connected
                if( isset($this->established) && $this->established ) {
                        return true;
                }
                
		// Try to open the socket connection to MPD with a 5 second timeout
		if( !$this->socket = @fsockopen( $this->host, $this->port, $errn, $errs, 5 ) ) {

			// Throw an MPDConnectionException along with the connection errors
			throw new MPDConnectionException( 'Connection failed: '.$errs, self::MPD_CONNECTION_FAILED );
		}

                // Clear connection messages
                while( !feof( $this->socket ) ) {

                        $response = trim( fgets( $this->socket ) );

                        // If the connection messages have cleared
                        if( strncmp( self::MPD_OK, $response, strlen( self::MPD_OK ) ) == 0 ) {

				// Successully connected
                                $this->established = true;

                                // Parse the MPD version from the response and replace the ending 0 with an x 
                                $this->version = preg_replace('/[0]$/','x', current( sscanf( $response, self::MPD_OK . " MPD %s\n" )));

				// Connected successfully
				return true;
                        }

                        // Check to see if there is a connection error message that was sent in the response
                        if( strncmp( self::MPD_ERROR, $response, strlen( self::MPD_ERROR ) ) == 0 ) {

				// Parse out the error message from the response
                                preg_match( '/^ACK \[(.*?)\@(.*?)\] \{(.*?)\} (.*?)$/', $response, $matches );

				// Throw an exception and include the response errors
                                throw new MPDConnectionException( 'Connection failed: '.$matches[4], self::MPD_CONNECTION_FAILED );
                        }
                }
      
		// Throw a general connection failed exception 
		throw new MPDConnectionException( 'Connection failed', self::MPD_CONNECTION_FAILED );
        }