diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0d20b6487c61e7d1bde93acf4a14b7a89083a16d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/client.py b/client.py
index efd6a04c545982cd12642838eb67cc23d484e3bc..820d574dd67dbc9f237d858e421ce1b1fa3b3db4 100644
--- a/client.py
+++ b/client.py
@@ -418,9 +418,11 @@ class Site(object):
 				self.wait(wait_token)
 			file.seek(0, 0)
 			
-	def parse(self, text, title = None):
-		kwargs = {'text': text}
+	def parse(self, text = None, title = None, page = None):
+		kwargs = {}
+		if text is not None: kwargs['text'] = text
 		if title is not None: kwargs['title'] = title
+		if page is not None: kwargs['page'] = page
 		result = self.api('parse', **kwargs)
 		return result['parse']
 	
@@ -528,11 +530,11 @@ class Site(object):
 		return listing.List(self, 'exturlusage', 'eu', limit = limit, **kwargs)	
 
 	def logevents(self, type = None, prop = None, start = None, end = None, 
-			dir = 'older', user = None, title = None, limit = None):
-		self.require(1, 9)
+			dir = 'older', user = None, title = None, limit = None, action = None):
+		self.require(1, 10)
 		
 		kwargs = dict(listing.List.generate_kwargs('le', prop = prop, type = type, start = start,
-			end = end, dir = dir, user = user, title = title))
+			end = end, dir = dir, user = user, title = title, action = action))
 		return listing.List(self, 'logevents', 'le', limit = limit, **kwargs)
 
 	# def protectedtitles requires 1.15
@@ -549,7 +551,7 @@ class Site(object):
 		
 		kwargs = dict(listing.List.generate_kwargs('rn', namespace = namespace))
 		return listing.List(self, 'random', 'rn', limit = limit, **kwargs)
-	
+
 	def recentchanges(self, start = None, end = None, dir = 'older', namespace = None, 
 				prop = None, show = None, limit = None, type = None):
 		self.require(1, 9)
diff --git a/listing.py b/listing.py
index 3c510959b5bf0f62bc69b828cf3e15b1e41b4bac..170547175ff9505156ab75497ff981808a62f33a 100644
--- a/listing.py
+++ b/listing.py
@@ -169,13 +169,13 @@ class PageList(GeneratorList):
 			return page.Page(self.site, self.site.namespaces[self.namespace] + ':' + name, info)
 		else:
 			# Guessing page class
-			namespace = self.guess_namespace(name)
-			if namespace == 14:
-				return Category(self.site, name, info)
-			elif namespace == 6:
-				return page.Image(self.site, name, info)
-			else:
-				return page.Page(self.site, name, info)
+			if type(name) is not int:
+				namespace = self.guess_namespace(name)
+				if namespace == 14:
+					return Category(self.site, name, info)
+				elif namespace == 6:
+					return page.Image(self.site, name, info)
+			return page.Page(self.site, name, info)
 		
 	def guess_namespace(self, name):
 		normal_name = page.Page.normalize_title(name)
diff --git a/page.py b/page.py
index 3c77acbf5f5e957b29a39f8d6821daa06d6a6308..0265eeea73bb15ee94b6caccab826c8d53136fb2 100644
--- a/page.py
+++ b/page.py
@@ -10,6 +10,7 @@ class Page(object):
 			return self.__dict__.update(name.__dict__)
 		self.site = site
 		self.name = name
+		self.section = None
 		
 		if not info:
 			if extra_properties:
@@ -20,8 +21,12 @@ class Page(object):
 				prop = 'info'
 				extra_props = ()
 			
-			info = self.site.api('query', prop = prop, titles = name, 
-				inprop = 'protection', *extra_props)
+			if type(name) is int:
+				info = self.site.api('query', prop = prop, pageids = name, 
+					inprop = 'protection', *extra_props)
+			else:
+				info = self.site.api('query', prop = prop, titles = name, 
+					inprop = 'protection', *extra_props)
 			info = info['query']['pages'].itervalues().next()
 		self._info = info
 				
@@ -41,7 +46,26 @@ class Page(object):
 		
 		self.last_rev_time = None
 		self.edit_time = None
-			
+
+	def redirects_to(self):
+		""" Returns the redirect target page, or None if the page is not a redirect page."""
+		info = self.site.api('query', prop = 'pageprops', titles = self.name, redirects = '')['query']
+		if 'redirects' in info:
+			for page in info['redirects']:
+				if page['from'] == self.name:
+					return Page(self.site, page['to'])
+			return None
+		else:
+			return None
+
+	def resolve_redirect(self):
+		""" Returns the redirect target page, or the current page if it's not a redirect page."""
+		target_page = self.redirects_to() 
+		if target_page == None:
+			return self
+		else:
+			return target_page
+
 	def __repr__(self):
 		return "<Page object '%s' for %s>" % (self.name.encode('utf-8'), self.site)
 
@@ -104,18 +128,20 @@ class Page(object):
 		if not self.exists:
 			return u''
 			
-		revs = self.revisions(prop = 'content|timestamp', limit = 1)
+		revs = self.revisions(prop = 'content|timestamp', limit = 1, section = section)
 		try:
 			rev = revs.next()
 			self.text = rev['*']
+			self.section = section
 			self.last_rev_time = rev['timestamp']
 		except StopIteration:
 			self.text = u''
+			self.section = None
 			self.edit_time = None
 		self.edit_time = time.gmtime()
 		return self.text
 	
-	def save(self, text = u'', summary = u'', minor = False, bot = True, **kwargs):
+	def save(self, text = u'', summary = u'', minor = False, bot = True, section = None, **kwargs):
 		"""Save text of page."""
 		if not self.site.logged_in and self.site.force_login:
 			# Should we really check for this?
@@ -126,6 +152,7 @@ class Page(object):
 			raise errors.ProtectedPageError(self)
 		
 		if not text: text = self.text
+		if not section: section = self.section
 		
 		if not self.site.writeapi:
 			return OldPage.save(self, text = text, summary = summary, minor = False)
@@ -136,6 +163,7 @@ class Page(object):
 		if self.last_rev_time: data['basetimestamp'] = time.strftime('%Y%m%d%H%M%S', self.last_rev_time)
 		if self.edit_time: data['starttimestamp'] = time.strftime('%Y%m%d%H%M%S', self.edit_time)
 		if bot: data['bot'] = '1'
+		if section: data['section'] = section
 		
 		data.update(kwargs)
 		
@@ -277,27 +305,29 @@ class Page(object):
 		else:
 			return listing.PageProperty(self, 'images', '', return_values = 'title')
 
-	def langlinks(self):
+	def langlinks(self, **kwargs):
 		self.site.require(1, 9)
-		return listing.PageProperty(self, 'langlinks', 'll', return_values = ('lang', '*'))
+		return listing.PageProperty(self, 'langlinks', 'll', return_values = ('lang', '*'), **kwargs)
 
-	def links(self, namespace = None, generator = True):
+	def links(self, namespace = None, generator = True, redirects = False):
 		self.site.require(1, 9)
 		kwargs = dict(listing.List.generate_kwargs('pl', namespace = namespace))
+		if redirects: kwargs['redirects'] = '1'
 		if generator:
-			return listing.PagePropertyGenerator(self, 'links', 'pl')
+			return listing.PagePropertyGenerator(self, 'links', 'pl', **kwargs)
 		else:
-			return listing.PageProperty(self, 'links', 'pl', return_values = 'title')
+			return listing.PageProperty(self, 'links', 'pl', return_values = 'title', **kwargs)
 
 	def revisions(self, startid = None, endid = None, start = None, end = None, 
 			dir = 'older', user = None, excludeuser = None, limit = 50, 
-			 prop = 'ids|timestamp|flags|comment|user', expandtemplates = False):
+			 prop = 'ids|timestamp|flags|comment|user', expandtemplates = False, section = None):
 		self.site.require(1, 8)
 		kwargs = dict(listing.List.generate_kwargs('rv', startid = startid, endid = endid,
 			start = start, end = end, user = user, excludeuser = excludeuser))
 		kwargs['rvdir'] = dir
 		kwargs['rvprop'] = prop
 		if expandtemplates: kwargs['rvexpandtemplates'] = '1'
+		if section: kwargs['rvsection'] = section
 		
 		return listing.RevisionsIterator(self, 'revisions', 'rv', limit = limit, **kwargs)