--- includes/actions/HistoryAction.php	2014-10-16 19:21:51.485431647 +0200
+++ includes_new/actions/HistoryAction.php	2014-10-16 19:21:25.489302729 +0200
@@ -614,7 +614,15 @@
 		}
 
 		# Text following the character difference is added just before running hooks
-		$s2 = Linker::revComment( $rev, false, true );
+		/*op-patch|TS|2009-11-05|HaloACL|Protected properties|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/Protected_properties
+		global $haclgProtectProperties;
+		$s2 = '';
+		if (!$haclgProtectProperties) {
+			// The comment for an article might reveal values of protected properties
+			$s2 = Linker::revComment( $rev, false, true );
+		}
+		/*op-patch|TS|2009-11-05|end*/
 
 		if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
 			$s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
--- includes/CategoryViewer.php	2014-10-16 19:21:51.433431367 +0200
+++ includes_new/CategoryViewer.php	2014-10-16 19:21:25.453302543 +0200
@@ -187,6 +187,12 @@
 	 */
 	function addSubcategory( Title $title, $sortkey, $pageLength ) {
 		wfDeprecated( __METHOD__, '1.17' );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			return;
+		}
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|end*/		
 		$this->addSubcategoryObject( Category::newFromTitle( $title ), $sortkey, $pageLength );
 	}
 
@@ -255,6 +261,12 @@
 	function addPage( $title, $sortkey, $pageLength, $isRedirect = false ) {
 		global $wgContLang;
 
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			return;
+		}
+		/*op-patch|TS|2009-06-19|end*/
 		$link = Linker::link( $title );
 		if ( $isRedirect ) {
 			// This seems kind of pointless given 'mw-redirect' class,
--- includes/diff/DairikiDiff.php	2014-10-16 19:21:49.785423203 +0200
+++ includes_new/diff/DairikiDiff.php	2014-10-16 19:21:24.353297091 +0200
@@ -758,6 +758,7 @@
 		return $lines;
 	}
 
+
 	/**
 	 * Check a Diff for validity.
 	 *
@@ -1385,6 +1386,7 @@
 
 	function _lines( $lines, $prefix = ' ', $color = 'white' ) {
 	}
+	// Remove property values before output if properties are protected
 
 	/**
 	 * HTML-escape parameter before calling this
@@ -1392,7 +1394,16 @@
 	 * @return string
 	 */
 	function addedLine( $line ) {
-		return $this->wrapLine( '+', 'diff-addedline', $line );
+		global $haclgProtectProperties;
+		if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) {
+			// Properties are not protected or no properties in line - everything can be processed
+			return $this->wrapLine( '+++', 'diff-addedline', $line );
+		} else { // properties in text
+			$regexpattern = '/::[^\]]*/';
+			$regexreplace = '::Property value removed by HaloACL';
+			$line2 = preg_replace($regexpattern, $regexreplace, $line);
+			return $this->wrapLine( '+', 'diff-addedline', $line2 );
+		} 	
 	}
 
 	/**
@@ -1401,7 +1412,16 @@
 	 * @return string
 	 */
 	function deletedLine( $line ) {
-		return $this->wrapLine( '−', 'diff-deletedline', $line );
+		global $haclgProtectProperties;
+		if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) {
+			// Properties are not protected or no properties in line - everything can be processed
+			return $this->wrapLine( '-', 'diff-addedline', $line );
+		} else { // properties in text
+			$regexpattern = '/::[^\]]*/';
+			$regexreplace = '::Property value removed by HaloACL';
+			$line2 = preg_replace($regexpattern, $regexreplace, $line);
+			return $this->wrapLine( '-', 'diff-addedline', $line2 );
+		} 		
 	}
 
 	/**
@@ -1410,7 +1430,16 @@
 	 * @return string
 	 */
 	function contextLine( $line ) {
-		return $this->wrapLine( '&#160;', 'diff-context', $line );
+		global $haclgProtectProperties;
+		if (!$haclgProtectProperties || !defined('SMW_VERSION') || !strpos($line, "::") ) {
+			// Properties are not protected or no properties in line - everything can be processed
+			return $this->wrapLine( '&#160', 'diff-addedline', $line );
+		} else { // properties in text
+			$regexpattern = '/::[^\]]*/';
+			$regexreplace = '::Property value removed by HaloACL';
+			$line2 = preg_replace($regexpattern, $regexreplace, $line);
+			return $this->wrapLine( '&#160', 'diff-addedline', $line2 );
+		} 			
 	}
 
 	/**
--- includes/Linker.php	2014-10-16 19:21:50.557427038 +0200
+++ includes_new/Linker.php	2014-10-16 19:21:24.641298519 +0200
@@ -1588,7 +1588,14 @@
 		} else {
 			$formatted = self::formatComment( $comment, $title, $local );
 			$formatted = wfMessage( 'parentheses' )->rawParams( $formatted )->escaped();
-			return " <span class=\"comment\">$formatted</span>";
+			global $haclgProtectProperties;
+			if (!$haclgProtectProperties || !defined('SMW_VERSION')) {
+				// Properties are not protected.
+				return " <span class=\"comment\">$formatted</span>";
+			} elseif ( !strpos($formatted, "::") ) { // no properties in text
+				return " <span class=\"comment\">$formatted</span>";
+			} 
+			return ""; // text had properties -> deleted
 		}
 	}
 
--- includes/QueryPage.php	2014-10-16 19:21:51.741432907 +0200
+++ includes_new/QueryPage.php	2014-10-16 19:21:25.709303812 +0200
@@ -588,6 +588,21 @@
 			# $res might contain the whole 1,000 rows, so we read up to
 			# $num [should update this to use a Pager]
 			for ( $i = 0; $i < $num && $row = $res->fetchObject(); $i++ ) {
+				/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+				// See http://dmwiki.ontoprise.com/dmwiki/index.php/SafeTitle
+				$title = null;
+				if (isset($row->namespace) && isset($row->title)) {
+					$title = Title::makeTitleSafe( $row->namespace, $row->title );
+				} else if (isset($row->id)) {
+					$title = Title::newFromID($row->id);
+				} else if (isset($row->type) && $row->type === 'Templates' 
+							&& isset($row->title)) {
+					$title = Title::makeTitleSafe(NS_TEMPLATE, $row->title);
+				}
+				if ($title && !$title->userCanReadEx()) {
+					continue;
+				}
+				/*op-patch|TS|2009-06-19|end*/				
 				$line = $this->formatResult( $skin, $row );
 				if ( $line ) {
 					$attr = ( isset( $row->usepatrol ) && $row->usepatrol && $row->patrolled == 0 )
--- includes/specials/SpecialAllpages.php	2014-10-16 19:21:52.505436684 +0200
+++ includes_new/specials/SpecialAllpages.php	2014-10-16 19:21:26.953309964 +0200
@@ -393,6 +393,12 @@
 				$out = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-chunk' ) );
 				while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) {
 					$t = Title::newFromRow( $s );
+					/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+					// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+					if ($t && !$t->userCanReadEx()) {
+						continue; 
+					}
+					/*op-patch|TS|2009-06-19|end*/  					
 					if ( $t ) {
 						$link = ( $s->page_is_redirect ? '<div class="allpagesredirect">' : '' ) .
 							Linker::link( $t ) .
--- includes/specials/SpecialCategories.php	2014-10-16 19:21:52.401436154 +0200
+++ includes_new/specials/SpecialCategories.php	2014-10-16 19:21:26.837309403 +0200
@@ -121,6 +121,13 @@
 
 	function formatRow( $result ) {
 		$title = Title::makeTitle( NS_CATEGORY, $result->cat_title );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		$title_nftv = Title::newFromTitleValue($title);
+		if (!$title_nftv->userCanReadEx()) {
+			return "";
+		}
+		/*op-patch|TS|2009-06-19|end*/		
 		$titleText = Linker::link( $title, htmlspecialchars( $title->getText() ) );
 		$count = $this->msg( 'nmembers' )->numParams( $result->cat_pages )->escaped();
 
--- includes/specials/SpecialContributions.php	2014-10-16 19:21:52.653437430 +0200
+++ includes_new/specials/SpecialContributions.php	2014-10-16 19:21:27.109310733 +0200
@@ -904,6 +904,9 @@
 			$classes = array();
 
 			$page = Title::newFromRow( $row );
+			if (!$page->userCanReadEx()) {
+				return "";
+			}			
 			$link = Linker::link(
 				$page,
 				htmlspecialchars( $page->getPrefixedText() ),
--- includes/specials/SpecialDeletedContributions.php	2014-10-16 19:21:52.505436684 +0200
+++ includes_new/specials/SpecialDeletedContributions.php	2014-10-16 19:21:26.941309923 +0200
@@ -154,6 +154,9 @@
 		wfProfileIn( __METHOD__ );
 
 		$page = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+		if (!$page->userCanReadEx()) {
+			return "";
+		}		
 
 		$rev = new Revision( array(
 			'title' => $page,
--- includes/specials/SpecialExport.php	2014-10-16 19:21:52.617437252 +0200
+++ includes_new/specials/SpecialExport.php	2014-10-16 19:21:27.065310555 +0200
@@ -422,8 +422,15 @@
 				$ns = $wgContLang->getNsText( $row->page_namespace );
 				$n = $ns . ':' . $n;
 			}
-
-			$pages[] = $n;
+/*op-patch|TS|2009-07-09|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			$t = Title::newFromText($n);
+			global $wgUser;
+			$allowed = wfRunHooks( 'userCan', array( &$t, &$wgUser, "read", &$result));
+			if ($allowed) {
+				$pages[] = $n;
+			}
+/*op-patch|TS|2009-07-09|end*/
 		}
 
 		return $pages;
--- includes/specials/SpecialListfiles.php	2014-10-16 19:21:52.357435954 +0200
+++ includes_new/specials/SpecialListfiles.php	2014-10-16 19:21:26.825309335 +0200
@@ -386,6 +386,31 @@
 		UserCache::singleton()->doQuery( $userIds, array( 'userpage' ), __METHOD__ );
 	}
 
+	function formatRow( $row ) {
+		
+		/*op-patch*/
+		$fieldNames = $this->getFieldNames();
+		$value = isset( $row->img_name ) ? $row->img_name : null;
+		$filePage = Title::makeTitleSafe( NS_FILE, $value );
+		if (!$filePage->userCanReadEx()) {
+			return "";
+		}
+		/*op-patch*/
+		$this->mCurrentRow = $row;  	# In case formatValue etc need to know
+		$s = Xml::openElement( 'tr', $this->getRowAttrs( $row ) );
+		$fieldNames = $this->getFieldNames();
+		foreach ( $fieldNames as $field => $name ) {
+			$value = isset( $row->$field ) ? $row->$field : null;
+			$formatted = strval( $this->formatValue( $field, $value ) );
+			if ( $formatted == '' ) {
+				$formatted = '&#160;';
+			}
+			$s .= Xml::tags( 'td', $this->getCellAttrs( $field, $value ), $formatted );
+		}
+		$s .= "</tr>\n";
+		return $s;
+	}	
+
 	function formatValue( $field, $value ) {
 		switch ( $field ) {
 			case 'thumb':
--- includes/specials/SpecialListredirects.php	2014-10-16 19:21:52.341435867 +0200
+++ includes_new/specials/SpecialListredirects.php	2014-10-16 19:21:26.785309154 +0200
@@ -123,6 +123,12 @@
 
 		# Find out where the redirect leads
 		$target = $this->getRedirectTarget( $result );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$target->userCanReadEx()) {
+			return;
+		}
+		/*op-patch|TS|2009-06-19|end*/ 		
 		if ( $target ) {
 			# Make a link to the destination page
 			$lang = $this->getLanguage();
--- includes/specials/SpecialNewimages.php	2014-10-16 19:21:52.405436174 +0200
+++ includes_new/specials/SpecialNewimages.php	2014-10-16 19:21:26.837309403 +0200
@@ -140,6 +140,9 @@
 		$user = User::newFromId( $row->img_user );
 
 		$title = Title::makeTitle( NS_FILE, $name );
+		if (!$title->userCanReadEx()) {
+			return "";
+		}		
 		$ul = Linker::link( $user->getUserpage(), $user->getName() );
 		$time = $this->getLanguage()->userTimeAndDate( $row->img_timestamp, $this->getUser() );
 
--- includes/specials/SpecialNewpages.php	2014-10-16 19:21:52.561436970 +0200
+++ includes_new/specials/SpecialNewpages.php	2014-10-16 19:21:27.029310361 +0200
@@ -305,6 +305,12 @@
 	 */
 	public function formatRow( $result ) {
 		$title = Title::newFromRow( $result );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			return "";
+		}
+		/*op-patch|TS|2009-06-19|end*/		
 
 		# Revision deletion works on revisions, so we should cast one
 		$row = array(
--- includes/specials/SpecialPrefixindex.php	2014-10-16 19:21:52.625437280 +0200
+++ includes_new/specials/SpecialPrefixindex.php	2014-10-16 19:21:27.065310555 +0200
@@ -208,6 +208,12 @@
 				$prefixLength = strlen( $prefix );
 				while ( ( $n < $this->maxPerPage ) && ( $s = $res->fetchObject() ) ) {
 					$t = Title::makeTitle( $s->page_namespace, $s->page_title );
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+					if ($t && !$t->userCanReadEx()) {
+						continue; 
+					}
+/*op-patch|TS|2009-06-19|end*/  					
 					if ( $t ) {
 						$displayed = $t->getText();
 						// Try not to generate unclickable links
--- includes/specials/SpecialProtectedpages.php	2014-10-16 19:21:52.561436970 +0200
+++ includes_new/specials/SpecialProtectedpages.php	2014-10-16 19:21:27.029310361 +0200
@@ -101,6 +101,12 @@
 		}
 
 		$title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			return "";
+		}
+		/*op-patch|TS|2009-06-19|end*/		
 		if ( !$title ) {
 			wfProfileOut( __METHOD__ );
 
--- includes/specials/SpecialProtectedtitles.php	2014-10-16 19:21:52.161434983 +0200
+++ includes_new/specials/SpecialProtectedtitles.php	2014-10-16 19:21:26.585308136 +0200
@@ -99,6 +99,13 @@
 			) . "\n";
 		}
 
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			return "";
+		}
+		/*op-patch|TS|2009-06-19|end*/		
+
 		$link = Linker::link( $title );
 		$description_items = array();
 		// Messages: restriction-level-sysop, restriction-level-autoconfirmed
--- includes/specials/SpecialRandompage.php	2014-10-16 19:21:52.517436746 +0200
+++ includes_new/specials/SpecialRandompage.php	2014-10-16 19:21:26.985310129 +0200
@@ -61,6 +61,12 @@
 		}
 
 		$title = $this->getRandomTitle();
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if (!$title->userCanReadEx()) {
+			$title = NULL;
+		}
+		/*op-patch|TS|2009-06-19|end*/		
 
 		if ( is_null( $title ) ) {
 			$this->setHeaders();
--- includes/specials/SpecialRecentchanges.php	2014-10-16 19:21:52.209435212 +0200
+++ includes_new/specials/SpecialRecentchanges.php	2014-10-16 19:21:26.613308280 +0200
@@ -464,6 +464,13 @@
 
 		$rclistOutput = $list->beginRecentChangesList();
 		foreach ( $rows as $obj ) {
+			/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+			// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+				$rc = RecentChange::newFromRow( $obj );
+				if (!$rc->getTitle()->userCanReadEx()) {
+					continue;
+				}
+			/*op-patch|TS|2009-06-19|end*/ 			
 			if ( $limit == 0 ) {
 				break;
 			}
--- includes/specials/SpecialSearch.php	2014-10-16 19:21:52.265435499 +0200
+++ includes_new/specials/SpecialSearch.php	2014-10-16 19:21:26.685308659 +0200
@@ -540,7 +540,28 @@
 		$out .= "<ul class='mw-search-results'>\n";
 		$result = $matches->next();
 		while ( $result ) {
-			$out .= $this->showHit( $result, $terms );
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			if (($result->getTitle() != NULL) && ($result->getTitle()->userCanReadEx())) {
+				global $haclgProtectProperties;
+				if (!$haclgProtectProperties || !defined('SMW_VERSION')) {
+					// Properties are not protected.
+					$out .= $this->showHit( $result, $terms );
+				} else {
+					$res0 = $this->showHit( $result, $terms );
+					$res1 = str_replace("'", "", $res0);
+					if ( !strpos($res1, "::<span class=searchmatch>") ) {
+						$regexpattern = '/::[^\]]*/';
+						$regexreplace = '::Property value protected by HaloACL';
+						$res2 = preg_replace($regexpattern, $regexreplace, $res1);
+						$out .= $res2;
+					} else {
+						$out .= '<p>Search result deleted by HaloACL</p>';
+					}
+
+				}
+			}
+/*op-patch|TS|2009-06-19|end*/  
 			$result = $matches->next();
 		}
 		$out .= "</ul>\n";
--- includes/specials/SpecialUndelete.php	2014-10-16 19:21:52.317435758 +0200
+++ includes_new/specials/SpecialUndelete.php	2014-10-16 19:21:26.745308951 +0200
@@ -1339,6 +1339,12 @@
 		$user = $this->getUser();
 		if ( $this->mCanView ) {
 			$titleObj = $this->getTitle();
+			/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+			// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			if ($titleObj && !$titleObj->userCanReadEx()) {
+				return ""; 
+			}
+			/*op-patch|TS|2009-06-19|end*/  			
 			# Last link
 			if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
 				$pageLink = htmlspecialchars( $this->getLanguage()->userTimeAndDate( $ts, $user ) );
@@ -1388,6 +1394,12 @@
 
 	private function formatFileRow( $row ) {
 		$file = ArchivedFile::newFromRow( $row );
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		if ($file->getTitle() && !$file->getTitle()->userCanReadEx()) {
+			return ""; 
+		}
+		/*op-patch|TS|2009-06-19|end*/ 		
 		$ts = wfTimestamp( TS_MW, $row->fa_timestamp );
 		$user = $this->getUser();
 
--- includes/specials/SpecialWatchlist.php	2014-10-16 19:21:52.281435580 +0200
+++ includes_new/specials/SpecialWatchlist.php	2014-10-16 19:21:26.685308659 +0200
@@ -430,6 +430,12 @@
 		foreach ( $res as $obj ) {
 			# Make RC entry
 			$rc = RecentChange::newFromRow( $obj );
+			/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+			// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			if (!$rc->getTitle()->userCanReadEx()) {
+				continue;
+			}
+			/*op-patch|TS|2009-06-19|end*/			
 			$rc->counter = $counter++;
 
 			if ( $wgShowUpdatedMarker ) {
--- includes/specials/SpecialWhatlinkshere.php	2014-10-16 19:21:52.513436732 +0200
+++ includes_new/specials/SpecialWhatlinkshere.php	2014-10-16 19:21:26.965310063 +0200
@@ -261,6 +261,12 @@
 		$out->addHTML( $this->listStart( $level ) );
 		foreach ( $rows as $row ) {
 			$nt = Title::makeTitle( $row->page_namespace, $row->page_title );
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			if (!$nt->userCanReadEx()) {
+				continue;
+			}
+/*op-patch|TS|2009-06-19|end*/  			
 
 			if ( $row->rd_from && $level < 2 ) {
 				$out->addHTML( $this->listItem( $row, $nt, true ) );
diff -u -r -N includes/Title.php includes_new/Title.php
--- includes/Title.php	2014-10-16 19:21:49.997424257 +0200
+++ includes_new/Title.php	2014-10-16 19:21:24.461297618 +0200
@@ -104,9 +104,15 @@
 	public static function newFromDBkey( $key ) {
 		$t = new Title();
 		$t->mDbkeyform = $key;
-		if ( $t->secureAndSplit() ) {
-			return $t;
-		} else {
+		if( $t->secureAndSplit() ) {
+		/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+		// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+					return $t->checkAccessControl();
+		}
+		/*op-patch|TS|2009-06-19|end*/  
+		//Replaced by patch		return $t;
+		
+		else {
 			return null;
 		}
 	}
@@ -159,7 +165,11 @@
 				$cachedcount++;
 				Title::$titleCache[$text] =& $t;
 			}
-			return $t;
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			return $t->checkAccessControl();
+/*op-patch|TS|2009-06-19|end*/  
+// Preplaced by patch			return $t;
 		} else {
 			$ret = null;
 			return $ret;
@@ -193,7 +203,11 @@
 
 		$t->mDbkeyform = str_replace( ' ', '_', $url );
 		if ( $t->secureAndSplit() ) {
-			return $t;
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			return $t->checkAccessControl();
+/*op-patch|TS|2009-06-19|end*/  
+// Preplaced by patch			return $t;
 		} else {
 			return null;
 		}
@@ -338,7 +352,12 @@
 		$t->mUrlform = wfUrlencode( $t->mDbkeyform );
 		$t->mTextform = str_replace( '_', ' ', $title );
 		$t->mContentModel = false; # initialized lazily in getContentModel()
-		return $t;
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+		$t = $t->checkAccessControl();
+ 		return $t;
+/*op-patch|TS|2009-06-19|end*/  
+// Preplaced by patch		return $t;
 	}
 
 	/**
@@ -360,7 +379,11 @@
 		$t = new Title();
 		$t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki );
 		if ( $t->secureAndSplit() ) {
-			return $t;
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+			return $t->checkAccessControl();
+/*op-patch|TS|2009-06-19|end*/  
+// Preplaced by patch			return $t;
 		} else {
 			return null;
 		}
@@ -1015,6 +1038,24 @@
 		return $result;
 	}
 
+	/*op-patch|TS|2012-02-24|HaloACL|HaloACLMemcache|start*/
+	// See http://dmwiki.ontoprise.com/index.php/HaloACLMemcache
+	public function userCanRead() {
+		if (!defined('HACL_HALOACL_VERSION')) {
+			//HaloACL is disabled
+			return $this->userCanReadOrig();
+		}
+		
+		global $wgUser;
+		$hmc = HACLMemcache::getInstance();
+		$allowed = $hmc->retrievePermission($wgUser, $this, 'read');
+		if ($allowed === -1) {
+			$allowed = $this->userCanReadOrig();
+			$hmc->storePermission($wgUser, $this, 'read', $allowed);
+		}
+		return $allowed;
+	}	
+
 	/**
 	 * Is this the mainpage?
 	 * @note Title::newFromText seems to be sufficiently optimized by the title
@@ -1348,6 +1389,25 @@
 		return implode( '/', $parts );
 	}
 
+/*op-patch|TS|2012-02-24|HaloACL|HaloACLMemcache|start*/
+// See http://dmwiki.ontoprise.com/index.php/HaloACLMemcache
+
+public function userCan($action, $doExpensiveQueries = true) {
+	if (!defined('HACL_HALOACL_VERSION')) {
+		//HaloACL is disabled
+		return $this->userCanOrig($action, $doExpensiveQueries);
+	}
+
+	global $wgUser;
+	$hmc = HACLMemcache::getInstance();
+	$allowed = $hmc->retrievePermission($wgUser, $this, $action);
+	if ($allowed === -1) {
+		$allowed = $this->userCanOrig($action, $doExpensiveQueries);
+		$hmc->storePermission($wgUser, $this, $action, $allowed);
+	}
+	return $allowed;
+}
+
 	/**
 	 * Get the base page name title, i.e. the part before the subpage name
 	 *
@@ -1760,7 +1820,7 @@
 	 * @return Bool
 	 * @todo fold these checks into userCan()
 	 */
-	public function userCanRead() {
+	public function userCanReadOrig() {
 		wfDeprecated( __METHOD__, '1.19' );
 		return $this->userCan( 'read' );
 	}
@@ -1794,7 +1854,7 @@
 	 *   unnecessary queries.
 	 * @return Bool
 	 */
-	public function userCan( $action, $user = null, $doExpensiveQueries = true ) {
+	public function userCanOrig( $action, $user = null, $doExpensiveQueries = true ) {
 		if ( !$user instanceof User ) {
 			global $wgUser;
 			$user = $wgUser;
@@ -2237,7 +2297,7 @@
 				# If it's a special page, ditch the subpage bit and check again
 				$name = $this->getDBkey();
 				list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name );
-				if ( $name ) {
+				if ( !is_null($name) ) { 
 					$pure = SpecialPage::getTitleFor( $name )->getPrefixedText();
 					if ( in_array( $pure, $wgWhitelistRead, true ) ) {
 						$whitelisted = true;
@@ -2257,6 +2317,9 @@
 			}
 		}
 
+		wfRunHooks( 'userCan', array( &$this, &$user, $action, &$whitelisted )  );
+
+
 		if ( !$whitelisted ) {
 			# If the title is not whitelisted, give extensions a chance to do so...
 			wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
@@ -4450,6 +4513,99 @@
 		return $this->getArticleID() != 0;
 	}
 
+/*op-patch|TS|2009-06-19|HaloACL|SafeTitle|start*/
+// See http://dmwiki.ontoprise.com:8888/dmwiki/index.php/SafeTitle
+	
+	/**
+	 * This function is called from the patches for HaloACL for secure listings 
+	 * (e.g. Spcecial:AllPages). It checks, whether the current user is allowed
+	 * to read the article for this title object. For normal pages this is 
+	 * evaluate in the method <userCanRead>. 
+	 * However, the special pages that generate listings, often create title 
+	 * objects before the can check their accessibility. The fallback mechanism
+	 * of HaloACL creates the title "Permission denied" for the article that 
+	 * must not be accessed. The listings would then show a link to "Permission
+	 * denied". So this function returns "false" for the title "Permission denied"
+	 * as well. 
+	 *
+	 * @return 
+	 * 		true, if this title can be read
+	 * 		false, if the title is protected or "Permission denied".
+	 */
+	public function userCanReadEx() {
+		if (!defined('HACL_HALOACL_VERSION')) {
+			//HaloACL is disabled
+			return true;
+		}
+		global $haclgContLang;
+		return $this->mTextform !== $haclgContLang->getPermissionDeniedPage() 
+		       && $this->userCanRead();
+	}
+	
+	/**
+	 * This function checks, if this title is accessible for the action of the
+	 * current request. If the action is unknown it is assumed to be "read".
+	 * If the title is not accessible, the new title "Permission denied" is 
+	 * returned. This is a fallback to protect titles if all other security 
+	 * patches fail.
+	 * 
+	 * While a page is rendered, the same title is often checked several times. 
+	 * To speed things up, the results of an accessibility check are internally
+	 * cached.  
+	 * 
+	 * This function can be disabled in HACL_Initialize.php or LocalSettings.php
+	 * by setting the variable $haclgEnableTitleCheck = false.
+	 *
+	 * @return 
+	 * 		$this, if access is granted on this title or
+	 * 		the title for "Permission denied" if not.
+	 */
+	private function checkAccessControl() {
+		if (!defined('HACL_HALOACL_VERSION')) {
+			//HaloACL is disabled
+			return $this;
+		}
+		global $haclgEnableTitleCheck;
+		if (isset($haclgEnableTitleCheck) && $haclgEnableTitleCheck === false) {
+			return $this;  
+		}
+		
+		static $permissionCache = array();
+		
+		global $wgRequest;
+		$action = $wgRequest->getVal( 'action', 'read');
+		$currentTitle = $wgRequest->getVal('title');
+		$currentTitle = str_replace( '_', ' ', $currentTitle);
+		if ($this->getFullText() != $currentTitle) {
+			$action = 'read';
+		}
+		$index = $this->getFullText().'-'.$action; // A bug was fixed here thanks to Dave MacDonald
+		$allowed = @$permissionCache[$index];
+		if (!isset($allowed)) {
+			switch ($action) {
+				case 'create':
+				case 'edit':
+				case 'move':
+				case 'annotate':
+					$allowed = $this->userCan($action);
+					break;
+				default:
+					$allowed = $this->userCanRead();
+			}
+			$permissionCache[$index] = $allowed;
+		}
+		if ($allowed === false) {
+			global $haclgContLang;
+			$etc = $haclgEnableTitleCheck;
+			$haclgEnableTitleCheck = false;
+			$t = Title::newFromURL($haclgContLang->getPermissionDeniedPage());
+			$haclgEnableTitleCheck = $etc;
+			return $t;
+		}
+		return $this;
+	}
+/*op-patch|TS|2009-06-19|end*/  	
+
 	/**
 	 * Should links to this title be shown as potentially viewable (i.e. as
 	 * "bluelinks"), even if there's no record by this title in the page