diff -x '*~' -ruN Trac-0.11.7/trac/versioncontrol/api.py patched-trac/trac/versioncontrol/api.py
--- Trac-0.11.7/trac/versioncontrol/api.py	2010-03-09 17:49:38.000000000 -0500
+++ patched-trac/trac/versioncontrol/api.py	2010-03-30 16:26:48.623597483 -0400
@@ -380,6 +380,17 @@
         """
         raise NotImplementedError
 
+    def set_content(self, content, commitmsg=None):
+        """
+        Set the content of the node. Add the commitmsg to the logs. If Node is
+        of type DIRECTORY this method raise an Error.
+        
+        If the Node doesn't exist it's created. 
+
+        Returns the revision Number that tags the commit.
+        """
+        raise NotImplementedError
+
     def get_entries(self):
         """Generator that yields the immediate child entries of a directory.
 
@@ -521,7 +532,7 @@
     access to view certain parts of a repository.
     """
 
-    def assert_permission(self, path):
+    def assert_permission(self, path, perm='r'):
         if not self.has_permission(path):
             raise PermissionDenied(_('Insufficient permissions to access '
                                      '%(path)s', path=path))
@@ -531,7 +542,7 @@
             raise PermissionDenied(_('Insufficient permissions to access '
                                      'changeset %(id)s', id=rev))
 
-    def has_permission(self, path):
+    def has_permission(self, path, perm='r'):
         return True
 
     def has_permission_for_changeset(self, rev):
diff -x '*~' -ruN Trac-0.11.7/trac/versioncontrol/svn_authz.py patched-trac/trac/versioncontrol/svn_authz.py
--- Trac-0.11.7/trac/versioncontrol/svn_authz.py	2010-03-09 17:49:38.000000000 -0500
+++ patched-trac/trac/versioncontrol/svn_authz.py	2010-03-30 16:26:48.623597483 -0400
@@ -89,13 +89,13 @@
 
         self.groups = self._groups()
 
-    def has_permission(self, path):
+    def has_permission(self, path, perm='r'):
         if path is None:
             return 1
 
         for p in parent_iter(path):
             if self.module_name:
-                for perm in self._get_section(self.module_name + ':' + p):
+                for perm in self._get_section(self.module_name + ':' + p, perm):
                     if perm is not None:
                         return perm
             for perm in self._get_section(p):
@@ -144,15 +144,15 @@
         # expand groups
         return expanded.keys()
 
-    def _get_section(self, section):
+    def _get_section(self, section, perm='r'):
         if not self.conf_authz.has_section(section):
             return
 
-        yield self._get_permission(section, self.auth_name)
+        yield self._get_permission(section, self.auth_name, perm)
 
         group_perm = None
         for g in self.groups:
-            p = self._get_permission(section, '@' + g)
+            p = self._get_permission(section, '@' + g, perm)
             if p is not None:
                 group_perm = p
 
@@ -161,9 +161,9 @@
 
         yield group_perm
 
-        yield self._get_permission(section, '*')
+        yield self._get_permission(section, '*', perm)
 
-    def _get_permission(self, section, subject):
+    def _get_permission(self, section, subject, perm='r'):
         if self.conf_authz.has_option(section, subject):
-            return 'r' in self.conf_authz.get(section, subject)
+            return perm in self.conf_authz.get(section, subject)
         return None
diff -x '*~' -ruN Trac-0.11.7/trac/versioncontrol/svn_fs.py patched-trac/trac/versioncontrol/svn_fs.py
--- Trac-0.11.7/trac/versioncontrol/svn_fs.py	2010-03-09 17:49:38.000000000 -0500
+++ patched-trac/trac/versioncontrol/svn_fs.py	2010-03-30 20:31:01.946510338 -0400
@@ -450,6 +450,9 @@
             revs.append(r)
         return revs
 
+    def delete_node(self, path, commitmsg):
+        return NotImplementedError
+
     def _history(self, path, start, end, pool):
         """`path` is a unicode path in the scope.
 
@@ -670,7 +673,12 @@
         else:
             self.root = fs.revision_root(self.fs_ptr, rev, self.pool())
         node_type = fs.check_path(self.root, self._scoped_path_utf8, pool)
-        if not node_type in _kindmap:
+        if node_type == core.svn_node_none:
+            self.created_rev = 0
+            self.created_path = self._scoped_path_utf8
+            self.rev = self.created_rev
+            node_type = core.svn_node_file
+        elif not node_type in _kindmap:
             raise NoSuchNode(path, rev)
         cp_utf8 = fs.node_created_path(self.root, self._scoped_path_utf8, pool)
         cp = _from_svn(cp_utf8)
@@ -700,6 +708,29 @@
         # is not destroyed before the stream object.
         s._pool = self.pool
         return s
+    def set_content(self,content,commitmsg="changed by trac",uname=""):
+        # this check is untested! 
+        self.authz.assert_permission(self.scoped_path, 'w')
+
+        # based on the putfile.py example of the subversion dist.
+        # open a transaction against HEAD.
+        rev = fs.youngest_rev(repos.fs(self.repos),self.pool())
+        txn = repos.fs_begin_txn_for_commit(self.repos, rev, uname,
+                                            commitmsg, self.pool())
+
+        root = fs.txn_root(txn,self.pool())
+        kind = fs.check_path(root,self._scoped_path_utf8,self.pool())
+
+        if kind == core.svn_node_none:
+            fs.make_file(root,self._scoped_path_utf8,self.pool())
+        elif not kind == core.svn_node_file:
+            raise TracError("Node is not a File.")
+        
+        handler, baton = fs.apply_textdelta(root,self._scoped_path_utf8, 
+                                            None, None, self.pool())
+
+        delta.svn_txdelta_send_string(content,handler,baton,self.pool())
+        return repos.fs_commit_txn(self.repos,txn,self.pool())
 
     def get_entries(self):
         if self.isfile:
diff -x '*~' -ruN Trac-0.11.7/trac/versioncontrol/tests/svn_fs.py patched-trac/trac/versioncontrol/tests/svn_fs.py
--- Trac-0.11.7/trac/versioncontrol/tests/svn_fs.py	2010-03-09 17:49:38.000000000 -0500
+++ patched-trac/trac/versioncontrol/tests/svn_fs.py	2010-03-30 16:26:48.627597713 -0400
@@ -197,6 +197,34 @@
         self.assertEqual('text/plain', node.content_type)
         self.assertEqual('A test.\n', node.get_content().read())
 
+    def test_set_file_content(self):
+        node = self.repos.get_node('/trunk/README.txt')
+        node.set_content('This is the test Content\n', 'change.')
+
+        # reload the repository for the newly commited change. 
+        self.repos = SubversionRepository(REPOS_PATH, None,
+                                          logger_factory('test'))
+
+        node = self.repos.get_node('/trunk/README.txt')
+        chgset = self.repos.get_changeset(self.repos.get_youngest_rev())
+
+        self.assertEqual('This is the test Content\n', 
+            node.get_content().read())
+        self.assertEqual('change.', chgset.message )
+
+    def test_delete_node(self):
+        node = self.repos.delete_node('/trunk/README.txt', "delete.")
+        
+        self.repos = SubversionRepository(REPOS_PATH, None,
+                                          logger_factory('test'))
+
+        node = self.repos.get_node('/trunk/README.txt')
+        chgset = self.repos.get_changeset(self.repos.get_youngest_rev())
+
+        self.assertNotEqual(Node.DIRECTORY, node.kind)
+        self.assertNotEqual(Node.FILE, node.kind)
+        self.assertEqual('delete.', chgset.message )
+
     def test_get_dir_properties(self):
         f = self.repos.get_node(u'/tête')
         props = f.get_properties()
diff -x '*~' -ruN Trac-0.11.7/trac/wiki/api.py patched-trac/trac/wiki/api.py
--- Trac-0.11.7/trac/wiki/api.py	2010-03-09 17:49:39.000000000 -0500
+++ patched-trac/trac/wiki/api.py	2010-03-30 16:26:48.631597453 -0400
@@ -35,6 +35,7 @@
 from trac.util.translation import _
 from trac.wiki.parser import WikiParser
 
+from trac.wiki.model_svn import WikiPage
 
 class IWikiChangeListener(Interface):
     """Extension point interface for components that should get notified about
@@ -198,8 +199,9 @@
                 cursor = db.cursor()
                 cursor.execute("SELECT DISTINCT name FROM wiki")
                 self._index = {}
-                for (name,) in cursor:
-                    self._index[name] = True
+                for page in WikiPage.select(self.env):
+                    self._index[page.name] = True
+
                 self._last_index_update = now
         finally:
             self._index_lock.release()
diff -x '*~' -ruN Trac-0.11.7/trac/wiki/macros.py patched-trac/trac/wiki/macros.py
--- Trac-0.11.7/trac/wiki/macros.py	2010-03-09 17:49:39.000000000 -0500
+++ patched-trac/trac/wiki/macros.py	2010-03-30 16:26:48.631597453 -0400
@@ -34,7 +34,7 @@
 from trac.wiki.api import IWikiMacroProvider, WikiSystem, parse_args
 from trac.wiki.formatter import format_to_html, format_to_oneliner, \
                                 extract_link, OutlineFormatter
-from trac.wiki.model import WikiPage
+from trac.wiki.model_svn import WikiPage
 from trac.web.chrome import add_stylesheet
 
 
diff -x '*~' -ruN Trac-0.11.7/trac/wiki/model.py patched-trac/trac/wiki/model.py
--- Trac-0.11.7/trac/wiki/model.py	2010-03-09 17:49:39.000000000 -0500
+++ patched-trac/trac/wiki/model.py	2010-03-30 16:26:48.631597453 -0400
@@ -169,3 +169,16 @@
         for version,ts,author,comment,ipnr in cursor:
             time = datetime.fromtimestamp(ts, utc)
             yield version,time,author,comment,ipnr
+
+    def select(cls, env, db=None):
+        if not db:
+            db = env.get_db_cnx()
+
+        cursor = db.cursor()
+        cursor.execute("SELECT DISTINCT name FROM wiki")
+        for (name,) in cursor:
+            yield WikiPage(env,name)
+
+    select = classmethod(select)
+
+
diff -x '*~' -ruN Trac-0.11.7/trac/wiki/model_svn.py patched-trac/trac/wiki/model_svn.py
--- Trac-0.11.7/trac/wiki/model_svn.py	1969-12-31 19:00:00.000000000 -0500
+++ patched-trac/trac/wiki/model_svn.py	2010-04-04 12:30:04.129060115 -0400
@@ -0,0 +1,130 @@
+# -*- coding: iso8859-1 -*-
+#
+# Copyright (C) 2003-2005 Edgewall Software
+# Copyright (C) 2005 Philipp Scholl <pscholl@bawue.de>
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://trac.edgewall.com/license.html.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://projects.edgewall.com/trac/.
+#
+# Author: Philipp Scholl <pscholl@bawue.de>
+
+from __future__ import generators
+import time
+
+from trac.core import *
+from trac.resource import Resource
+#from trac.wiki.api import WikiSystem
+from trac.versioncontrol.api import Node
+
+
+class WikiPage(object):
+    """Represents a wiki page (new or existing)."""
+
+    def __init__(self, env, name=None, version=None, db=None):
+        self.env = env
+        self.root = env.config.get( 'wiki', 'svn_root' )
+        if not env.get_repository().get_node(self.root).kind in (Node.DIRECTORY, Node.FILE):
+            raise TracError( "wiki root couldn't be found!" )
+        if self.root[:-1] != '/': self.root += '/'
+        if isinstance(name, Resource):
+            self.resource = name
+            name = self.resource.id
+        else:
+            self.resource = Resource('wiki', name, version)
+        self.name = name
+        if name:
+            self._fetch(name, version, db)
+        else:
+            self.version = 0
+            self.text = ''
+            self.readonly = 0
+        self.old_text = self.text
+        self.old_readonly = self.readonly
+        
+    def _fetch(self, name, version=None, db=None):
+        repos = self.env.get_repository()
+        try:
+            if version:
+                node = repos.get_node(self.root+name,version)
+                self.text = node.get_content().read()
+                self.version = version
+                self.readonly = 0
+            else:
+                node = repos.get_node(self.root+name)
+                self.text = node.get_content().read()
+                history = node.get_history()
+                self.version = 0
+                for path, rev, chg in history:
+                    if self.version < rev: self.version = rev
+                self.readonly = 0
+        except Exception:
+            self.version = 0
+            self.text = ''
+            self.readonly = 0
+        except:
+            repos.close()
+
+    exists = property(fget=lambda self: self.version > 0)
+
+    def delete(self, version=None, db=None):
+        assert self.exists, 'Cannot delete non-existent page'
+        if version:
+            raise NotImplementedError( "deletion of versions not supported in \
+            wiki_svn" )
+        repos = self.env.get_repository()
+        repos.delete_node(self.root+self.name)
+
+    def save(self, author, comment, remote_addr, t=None, db=None):
+        repos = self.env.get_repository()
+        
+        # make sure that noone can escape the wiki root.
+        if self.name.find( "..") != -1:
+            raise TracError( ".. not allowed in wiki names." )
+
+        node = repos.get_node(self.root+self.name)
+
+        commitmsg  = self.name+" edited by "+author+" from "+remote_addr+"\n"
+        commitmsg += comment
+        self.version = node.set_content(self.text, commitmsg, author)
+        self.resource = self.resource(version=self.version)
+
+        if t is None:
+            t = time.time()
+            
+#        for listener in WikiSystem(self.env).change_listeners:
+#            if self.version == repos.get_youngest_rev():
+#                listener.wiki_page_added(self)
+#            else:
+#                listener.wiki_page_changed(self, self.version, t, author,
+#                                           comment, remote_addr)
+
+    def get_history(self, db=None):
+        repos = self.env.get_repository()
+
+        history = repos.get_path_history(self.root+self.name)
+
+        for path, rev, kind in history:
+            chgset = repos.get_changeset(rev)
+            yield rev,chgset.date,chgset.author,chgset.message,"missing"
+
+    def select(cls, env, db=None):
+        if not 'get_repository' in dir(env):
+            return
+        repos = env.get_repository()
+        dnode = repos.get_node( env.config.get('wiki', 'svn_root') )
+        
+        for node in dnode.get_entries():
+            if node.kind == Node.DIRECTORY:
+                for subnode in node.get_entries():
+                    yield WikiPage(env,node.get_name())
+            yield WikiPage(env,node.get_name())
+
+    select = classmethod(select)
+
+
diff -x '*~' -ruN Trac-0.11.7/trac/wiki/web_ui.py patched-trac/trac/wiki/web_ui.py
--- Trac-0.11.7/trac/wiki/web_ui.py	2010-03-09 17:49:39.000000000 -0500
+++ patched-trac/trac/wiki/web_ui.py	2010-09-15 16:19:30.424570093 -0400
@@ -42,7 +42,7 @@
 from trac.web import IRequestHandler
 from trac.wiki.api import IWikiPageManipulator, WikiSystem
 from trac.wiki.formatter import format_to
-from trac.wiki.model import WikiPage
+from trac.wiki.model_svn import WikiPage
  
 class InvalidWikiPage(TracError):
     """Exception raised when a Wiki page fails validation.

