function __construct( array $argv, qp_PollView $view ) {
		parent::__construct( $argv, $view );
		# Split header / body
		# Includes surrounding newlines and header's curly braces into match in parentheses
		# because raw question bodies has to be trimmed from single surrounding newlines.
		# Otherwise, these newlines will cause false positive detection of multiline proposals.
		self::$splitPattern = '/((?:$.^|^)\s*{' . self::$headerPattern . '\}\s*$.^)/msu';
		# match header
		# Does not include surrounding newlines and header's curly braces into match in parentheses
		# because we need to parse only the inner part (common question and optional categories).
		self::$matchPattern = '/^\s*{(' . self::$headerPattern . ')\}\s*$/msu';
		# dependance attr
		if ( array_key_exists( 'dependance', $argv ) ) {
			$this->dependsOn = trim( $argv['dependance'] );
			if ( $this->dependsOn === 'dependance' ) {
				$this->dependsOn = '';
			}
		}
		# interpretation attr
		if ( array_key_exists( 'interpretation', $argv ) ) {
			$this->interpretation = trim( $argv['interpretation'] );
		}
		# randomize attr
		if ( array_key_exists( 'randomize', $argv ) ) {
			if ( $argv['randomize'] === 'randomize' ) {
				$this->randomQuestionCount = 1;
			} else {
				$this->randomQuestionCount = intval( trim( $argv['randomize'] ) );
				if ( $this->randomQuestionCount < 0 ) {
					$this->randomQuestionCount = 0;
				}
			}
		}
		# max_attempts attr
		$this->maxAttempts = qp_Setup::$max_submit_attempts;
		if ( array_key_exists( 'max_attempts', $argv ) ) {
			$this->maxAttempts = intval( trim( $argv['max_attempts'] ) );
			# do not allow to specify more submit attempts than is set by global level in qp_Setup
			if ( qp_Setup::$max_submit_attempts > 0 &&
					# also does not allow to set infinite number ( < 1 ) when global level is finite ( > 0 )
					( $this->maxAttempts < 1 ||
						$this->maxAttempts > qp_Setup::$max_submit_attempts ) ) {
				$this->maxAttempts = qp_Setup::$max_submit_attempts;
			}
		}
		# negative values are possible however meaningless (<=0 is infinite, >0 is finite)
		if ( $this->maxAttempts < 0 ) {
			$this->maxAttempts = 0;
		}
		# order_id is used to sort out polls on the Special:PollResults statistics page
		$this->mOrderId = self::$sOrderId;
		# Determine if this poll is being corrected or not, according to the pollId
		$this->mBeingCorrected = ( qp_Setup::$request->wasPosted() && qp_Setup::$request->getVal( 'pollId' ) == $this->mPollId );
	}
	function getPageHeader() {
		global $wgLang, $wgContLang;
		$link = "";
		if ( $this->pid !== null ) {
			$pollStore = new qp_PollStore( array( 'from' => 'pid', 'pid' => $this->pid ) );
			if ( $pollStore->pid !== null ) {
				$pollStore->loadQuestions();
				$poll_title = Title::makeTitle( intval( $this->ns ), $this->title, qp_AbstractPoll::s_getPollTitleFragment( $this->poll_id, '' ) );
				$pagename = qp_Setup::specialchars( $wgContLang->convert( $poll_title->getPrefixedText() ) );
				$pollname = qp_Setup::specialchars( $this->poll_id );
				$head = array();
				$head[] = $this->showPollActionsList(
					$pollStore->pid,
					$pollStore->mPollId,
					$poll_title
				);
				$head[] = wfMsg( 'qp_header_line_qpul', wfMsg( 'qp_users_link' ), $pagename, $pollname );
				$ques_found = false;
				foreach ( $pollStore->Questions as $qdata ) {
					if ( $qdata->question_id == $this->question_id ) {
						$ques_found = true;
						break;
					}
				}
				if ( $ques_found ) {
					$qpa = wfMsg( 'qp_header_line_qucl', $this->question_id, qp_Setup::entities( $qdata->CommonQuestion ) );
					if ( array_key_exists( $this->cat_id, $qdata->Categories ) ) {
						$categ = &$qdata->Categories[ $this->cat_id ];
						$proptext = $qdata->ProposalText[ $this->proposal_id ];
						$cat_name = $categ['name'];
						if ( array_key_exists( 'spanId', $categ ) ) {
							$cat_name =  wfMsg( 'qp_full_category_name', $cat_name, $qdata->CategorySpans[ $categ['spanId'] ]['name'] );
						}
						$head[] = wfMsg( 'qp_header_line_qucl',
							$this->question_id,
							qp_Setup::entities( $qdata->CommonQuestion ),
							qp_Setup::entities( $proptext ),
							qp_Setup::entities( $cat_name ) );
						qp_Renderer::applyAttrsToRow( $head, array( '__tag' => 'li', '__end' => "\n" ) );
						$head = array( '__tag' => 'ul', 'class' => 'head', $head );
						$link = PollResults::getPollsLink() .
							PollResults::getUsersLink() .
							qp_Renderer::renderTagArray( $head );
					}
				}
			}
		}
		return $link;
	}
	function __construct( array $argv, qp_PollStatsView $view ) {
		parent::__construct( $argv, $view );
		$this->pollAddr = trim( $argv['address'] );
	}
	function setShowResults( $showresults ) {
		# setup question's showresults when global showresults != 0
		if ( qp_Setup::$global_showresults != 0 && $showresults !== null ) {
			# use the value from the question
			$this->showResults = qp_AbstractPoll::parseShowResults( $showresults );
			# apply undefined attributes from the poll's showresults definition
			foreach ( $this->pollShowResults as $attr => $val ) {
				if ( $attr != 'type' && !isset( $this->showResults[$attr] ) ) {
					$this->showResults[$attr] = $val;
				}
			}
		} else {
			# use the value "inherited" from the poll
			$this->showResults = $this->pollShowResults;
		}
	}
	/**
	 * Get full title (with fragment part) of the current poll.
	 * To get an URI path, use Title::getFullText()/getPrefixedText() on it.
	 * @return Title object
	 */
	function getTitle() {
		if ( $this->mArticleId === 0 ) {
			throw new MWException( __METHOD__ . ' cannot be called for unsaved new pages' );
		}
		if ( is_null( $this->mArticleId ) ) {
			throw new MWException( 'Unknown article id in ' . __METHOD__ );
		}
		if ( is_null( $this->mPollId ) ) {
			throw new MWException( 'Unknown poll id in ' . __METHOD__ );
		}
		$res = Title::newFromID( $this->mArticleId );
		if ( !( $res instanceof Title ) ) {
			throw new MWException( 'Cannot create poll title in ' . __METHOD__ );
		}
		$res->setFragment( qp_AbstractPoll::s_getPollTitleFragment( $this->mPollId ) );
		return $res;
	}