Commits

Lynn Rees  committed 7976ca0

Initial revision

  • Participants

Comments (0)

Files changed (17)

File CVSROOT/checkoutlist

+# The "checkoutlist" file is used to support additional version controlled
+# administrative files in $CVSROOT/CVSROOT, such as template files.
+#
+# The first entry on a line is a filename which will be checked out from
+# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
+# The remainder of the line is an error message to use if the file cannot
+# be checked out.
+#
+# File format:
+#
+#	[<whitespace>]<filename><whitespace><error message><end-of-line>
+#
+# comment lines begin with '#'

File CVSROOT/commitinfo

+# The "commitinfo" file is used to control pre-commit checks.
+# The filter on the right is invoked with the repository and a list 
+# of files to check.  A non-zero exit of the filter program will 
+# cause the commit to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT.  For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".

File CVSROOT/config

+# Set this to "no" if pserver shouldn't check system users/passwords
+#SystemAuth=no
+
+# Set `PreservePermissions' to `yes' to save file status information
+# in the repository.
+#PreservePermissions=no
+
+# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
+# level of the new working directory when using the `cvs checkout'
+# command.
+#TopLevelAdmin=no

File CVSROOT/cvswrappers

+# This file affects handling of files based on their names.
+#
+# The -t/-f options allow one to treat directories of files
+# as a single file, or to transform a file in other ways on
+# its way in and out of CVS.
+#
+# The -m option specifies whether CVS attempts to merge files.
+#
+# The -k option specifies keyword expansion (e.g. -kb for binary).
+#
+# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
+#
+#  wildcard	[option value][option value]...
+#
+#  where option is one of
+#  -f		from cvs filter		value: path to filter
+#  -t		to cvs filter		value: path to filter
+#  -m		update methodology	value: MERGE or COPY
+#  -k		expansion mode		value: b, o, kkv, &c
+#
+#  and value is a single-quote delimited value.
+# For example:
+#*.gif -k 'b'

File CVSROOT/editinfo

+# The "editinfo" file is used to allow verification of logging
+# information.  It works best when a template (as specified in the
+# rcsinfo file) is provided for the logging procedure.  Given a
+# template with locations for, a bug-id number, a list of people who
+# reviewed the code before it can be checked in, and an external
+# process to catalog the differences that were code reviewed, the
+# following test can be applied to the code:
+#
+#   Making sure that the entered bug-id number is correct.
+#   Validating that the code that was reviewed is indeed the code being
+#       checked in (using the bug-id number or a seperate review
+#       number to identify this particular code set.).
+#
+# If any of the above test failed, then the commit would be aborted.
+#
+# Actions such as mailing a copy of the report to each reviewer are
+# better handled by an entry in the loginfo file.
+#
+# One thing that should be noted is the the ALL keyword is not
+# supported.  There can be only one entry that matches a given
+# repository.

File CVSROOT/loginfo

+# The "loginfo" file controls where "cvs commit" log information
+# is sent.  The first entry on a line is a regular expression which must match
+# the directory that the change is being made to, relative to the
+# $CVSROOT.  If a match is found, then the remainder of the line is a filter
+# program that should expect log information on its standard input.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name ALL appears as a regular expression it is always used
+# in addition to the first matching regex or DEFAULT.
+#
+# You may specify a format string as part of the
+# filter.  The string is composed of a `%' followed
+# by a single format character, or followed by a set of format
+# characters surrounded by `{' and `}' as separators.  The format
+# characters are:
+#
+#   s = file name
+#   V = old version number (pre-checkin)
+#   v = new version number (post-checkin)
+#
+# For example:
+#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
+# or
+#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog

File CVSROOT/modules

+# Three different line formats are valid:
+#	key	-a    aliases...
+#	key [options] directory
+#	key [options] directory files...
+#
+# Where "options" are composed of:
+#	-i prog		Run "prog" on "cvs commit" from top-level of module.
+#	-o prog		Run "prog" on "cvs checkout" of module.
+#	-e prog		Run "prog" on "cvs export" of module.
+#	-t prog		Run "prog" on "cvs rtag" of module.
+#	-u prog		Run "prog" on "cvs update" of module.
+#	-d dir		Place module in directory "dir" instead of module name.
+#	-l		Top-level directory only -- do not recurse.
+#
+# NOTE:  If you change any of the "Run" options above, you'll have to
+# release and re-checkout any working directories of these modules.
+#
+# And "directory" is a path to a directory relative to $CVSROOT.
+#
+# The "-a" option specifies an alias.  An alias is interpreted as if
+# everything on the right of the "-a" had been typed on the command line.
+#
+# You can encode a module within a module by using the special '&'
+# character to interpose another module into the current module.  This
+# can be useful for creating a module that consists of many directories
+# spread out over the entire source repository.

File CVSROOT/notify

+# The "notify" file controls where notifications from watches set by
+# "cvs watch add" or "cvs edit" are sent.  The first entry on a line is
+# a regular expression which is tested against the directory that the
+# change is being made to, relative to the $CVSROOT.  If it matches,
+# then the remainder of the line is a filter program that should contain
+# one occurrence of %s for the user to notify, and information on its
+# standard input.
+#
+# "ALL" or "DEFAULT" can be used in place of the regular expression.
+#
+# For example:
+#ALL mail %s -s "CVS notification"

File CVSROOT/rcsinfo

+# The "rcsinfo" file is used to control templates with which the editor
+# is invoked on commit and import.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being made to, relative to the
+# $CVSROOT.  For the first match that is found, then the remainder of the
+# line is the name of the file that contains the template.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".

File CVSROOT/taginfo

+# The "taginfo" file is used to control pre-tag checks.
+# The filter on the right is invoked with the following arguments:
+#
+# $1 -- tagname
+# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
+# $3 -- repository
+# $4->  file revision [file revision ...]
+#
+# A non-zero exit of the filter program will cause the tag to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT.  For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".

File CVSROOT/verifymsg

+# The "verifymsg" file is used to allow verification of logging
+# information.  It works best when a template (as specified in the
+# rcsinfo file) is provided for the logging procedure.  Given a
+# template with locations for, a bug-id number, a list of people who
+# reviewed the code before it can be checked in, and an external
+# process to catalog the differences that were code reviewed, the
+# following test can be applied to the code:
+#
+#   Making sure that the entered bug-id number is correct.
+#   Validating that the code that was reviewed is indeed the code being
+#       checked in (using the bug-id number or a seperate review
+#       number to identify this particular code set.).
+#
+# If any of the above test failed, then the commit would be aborted.
+#
+# Actions such as mailing a copy of the report to each reviewer are
+# better handled by an entry in the loginfo file.
+#
+# One thing that should be noted is the the ALL keyword is not
+# supported.  There can be only one entry that matches a given
+# repository.

File psilib-test/AUTHORS

+-- AUTHORS for psilib 0.01
+
+Project Administrator
+	L. C. Rees <xanimal@users.sourceforge.net>
+
+Code Maintainence:
+	Pat Hayes <pathayes@users.sourceforge.net>
+	L. C. Rees <xanimal@users.sourceforge.net>
+
+Current Contributors:
+	Pat Hayes <pathayes@users.sourceforge.net>
+	L. C. Rees <xanimal@users.sourceforge.net>
+	
+Original Author:
+        L. C. Rees <xanimal@users.sourceforge.net>
+
+Past Contributors:
+	D. E. Evans <santayana@users.sourceforge.net>

File psilib-test/COPYRIGHT

+The Portable Site Information Project.
+
+Copyright (c) 1999 - 2002 Lynn C. Rees.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1.  Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+2.  Redistributions in binary form must reproduce the above copyright notice, 
+    this list of conditions and the following disclaimer in the documentation 
+    and/or other materials provided with the distribution.
+3.  Neither the name of the Portable Site Information Project nor the names
+    of its contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File psilib-test/ChangeLog

+ChangeLog for 0.01
+
+Changes from 0.01.0ALPHA to 00.01.1-test:
+- Documentation updated to reflect 0.01.1-test change. 
+- Schema added to the specification.
+- namespace updated.
+- created class "Generator" to wrapper existing functions and DOM structure.
+- created functions 'createPsiFile', 'createPsiArchive', 'setPsiSource', 'setPsiDestination',  '_createPsiNode', '_createPsiRoot', '_createPsiMap', "_walkPsiSourceDirectory', and '__init__', some based on existing.
+- removed function 'makePsiDirMapFallBack' and merged functionality with '_createPsiMap'.
+- cleaned up variable names.
+- redid __main__ to use new class methods.
+
+See diff in CVS for further details. 
+
+Changes from 0.00.0 to 0.01.0ALPHA:
+  - Scans recursively the directory tree from which the psilib.py is executed.
+  - Makes a list of "collections" and "resources."
+  - Saves as test.psi XML 1.0 file, or test.psa (gzip--default--or zip compressed archive).

File psilib-test/README

+-- README for psilib-0.01.1ALPHA
+
+Unix Installation:
+--------------------------------
+1. Extract the psilib.x.xx.xALPHA tarball, with the following command, into a directory of your choice, (we recommend /usr/local/ for Unix based systems and users who have root access; otherwise, extract to your $HOME directory):
+
+     cd /usr/local/
+     tar -xzf psilib.xx.xALPHA
+
+2. The shebang line (#!) may need to be changed to reflect the path to python.
+
+3. Add the psilib/bin directory to your PATH.
+
+4. Ensure the psilib.py has 755 permissions.

File psilib-test/bin/psilib.py

+#! /usr/bin/env python
+#
+# Portable Site Information Project.
+#
+# Copyright (c) 1999 - 2002 L. C. Rees.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without 
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, 
+#    this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice, 
+#    this list of conditions and the following disclaimer in the documentation 
+#    and/or ot her materials provided with the distribution.
+# 3. Neither the name of the Portable Site Information Project nor the names
+#    of its contributors may be used to endorse or promote products derived
+#    from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" 
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+# POSSIBILITY OF SUCH DAMAGE.
+
+usage = '''psilib outputs PSI map of DIRECTORY to DESTINATION 
+
+Usage: psilib.py [OPTION]... DIRECTORY DESTINATION
+
+Examples:
+    psilib.py /home home.psi    # Output PSI map of /home to home.psi
+    psilib.py -a /home home.psa # Output PSI map of /home to archive home.psa
+    
+OPTION:
+    -a                      archive PSI map
+    -h                      show help on command line options for psilib'''
+
+import os
+
+class Generator:
+    try:
+        global evaluate, pprint, cl
+        from Ft.Xml.cDomlette import implementation
+        from xml.dom.ext import PrettyPrint as pprint
+        from cStringIO import StringIO as stringio
+        from xml.xpath import Evaluate as evaluate
+    except ImportError: from xml.dom.minidom import Document as document
+    try: from gzip import GzipFile as gzipf
+    except ImportError: from zipfile import ZipFile as zipf
+
+    ns = 'urn:psilib:PSI:0:4:core'
+    sp, cc, tmp = ns, ns, ns
+    try: doc = implementation.createDocument(ns, None, None)
+    except NameError: doc = document()
+    
+    def _createNode(self, e, a = None, v = None):
+        node = self.doc.createElementNS(None, e)
+        try: node.setAttributeNS(None, a, v)
+        except TypeError: pass
+        except UnicodeError:
+            try:
+                v = unicode(v, 'utf-8', 'ignore')
+                node.setAttributeNS(None, a, v)
+            except TypeError: pass
+        return node
+
+    def _createRoot(self):
+        self.root = self._createNode('psi', 'xmlns', self.ns)
+        self.doc.appendChild(self.root)
+
+    def _createMap(self, u, d, f):
+        self.sp, co, id = d.split(os.sep), 'collection', 'id'
+        try:
+            self.sp[-1][0]
+            self.tmp = self._createNode(co, id, self.sp[-1])
+        except IndexError:
+            self.tmp = self._createNode(co, id, self.sp[0])
+        for i in f:
+            fp = os.path.join(d, i)
+            if os.path.isfile(fp):
+                fs = os.path.split(fp)
+                self.tmp.appendChild(self._createNode('resource', id, fs[1]))
+        try:
+            try:
+                if self.cc != self.sp[-2]:
+                    self.cl = evaluate('//collection[@id="' + self.sp[-2] + '"]', self.root)
+            except IndexError: pass
+            try:
+                self.cl[0].insertBefore(self.tmp, self.cl[0].firstChild)
+                self.cc = self.cl[0].getAttributeNS(None, id)
+            except (AttributeError, IndexError):
+                self.root.insertBefore(self.tmp, self.root.firstChild)
+                self.cl = [self.tmp]
+        except (IndexError, AttributeError, NameError):
+            cl = self.root.getElementsByTagName(co)
+            try:
+                cl[0].getAttribute(id)
+                for cu in cl:
+                    if cu.getAttribute(id) == self.sp[-2]:
+                        cu.insertBefore(self.tmp, cu.firstChild)
+            except IndexError:
+                self.root.insertBefore(self.tmp, self.root.firstChild)            
+                        
+    def _walkSourceDirectory(self, src = None):
+        os.path.walk(src, self._createMap, self.ns)
+
+    def setSource(self, src):
+        self.source = src
+        try:
+            if dir(self.root): del(self.root)
+            if self.doc.hasChildNodes():
+                self.doc.removeChild(self.doc.firstChild)
+        except AttributeError: pass
+        self._createRoot()
+        self._walkSourceDirectory(self.source)
+        
+    def setDestination(self, dest): self.destination = dest
+
+    def __init__(self, src = None, dest = None):
+        if src != None:
+            self.setSource(src)
+            self.setDestination(dest)      
+
+    def writeFile(self, dest = None):
+        if dest == None: dest = self.destination
+        if dest.find('.psi') and dest.find('.xml') == -1:
+            dest = '%s%s' % (dest, '.psi')
+        f = open(dest, 'w')
+        try: pprint(self.doc, f)
+        except NameError: self.doc.writexml(f)
+        f.close()
+
+    def writeArchive(self, dest = None):
+        if dest == None: dest = self.destination
+        if dest.find('.psa') == -1: dest = '%s%s' % (dest, '.psa')
+        try:
+            g = self.stringio()
+            pprint(self.doc, g)
+            f = g.getvalue()
+        except (NameError, AttributeError): f = self.doc.toxml()
+        try: zf = self.gzipf(dest, 'wb', 9)
+        except NameError: zf = self.zipf(dest, 'w')
+        zf.write(f)
+        zf.close()
+
+if __name__ == '__main__':
+    import sys
+    
+    def quitter(x):
+        y = x.lower()
+        if y == 'q':
+            print usage
+            sys.exit()
+
+    arc, stmsg = 0, 'Press "q" to quit and view online help'
+    for s in sys.argv:
+        if s != sys.argv[0]:
+            if s.find('-h') != -1: quitter('q')
+            elif s.find('-a') != -1: arc = 1
+            else:
+                try:
+                    if dir(n1): n2 = s
+                except NameError: n1 = s
+
+    def sa(x):
+        global src
+        src = x
+        if os.path.isfile(src):
+            print "Invalid argument: source must be directory"
+            quitter('q')
+        else: print 'Processing source directory...'
+
+    def fa(x):
+        global fdst
+        fdst = x
+
+    def aa(x):
+        global adst
+        adst = x
+
+    try: sa(n1)        
+    except NameError:
+        print stmsg
+        mc = 1
+        print 'Invalid argument: no source directory specified'
+        n1 = raw_input('Enter source directory pathname: ')
+        quitter(n1)
+        sa(n1)
+
+    def truePath():
+        try:
+            fc = mc
+        except NameError:
+            print stmsg
+        print 'Invalid argument: no destination specified'
+        n2 = raw_input('Create PSI archive? (yes/no): ')
+        quitter(n2)
+        if n2 == 'no':
+            n2 = raw_input('Enter destination pathname: ')
+            quitter(n2)
+            fa(n2)
+        else:
+            n2 = raw_input('Enter archive pathname: ')
+            quitter(n2)
+            aa(n2)        
+
+    if arc == 1:
+        try: aa(n2)
+        except NameError:
+            print 'Invalid usage: -a: no archive name found'
+            truePath()
+    else:
+        try:
+            if dir(n2): fa(n2)
+        except NameError: truePath()
+    
+    try:
+        print 'Generating PSI map...'
+        psi = Generator(src, fdst)
+        psi.writeFile()
+    except NameError:
+        print 'Generating PSI archive...'
+        psi = Generator(src, adst)
+        psi.writeArchive()
+
+    print 'Processing complete.'

File psilib-test/doc/psi-spec.txt

+Specification: Portable Storage Information
+Contributors: Patrick W. Hayes, Jr., L. C. Rees, D. E. Evans
+Version: 0.4.1
+Created: 3.22.2002
+Modified: 6.27.2002
+Copyright 1999 - 2002 L. C. Rees.  All rights reserved.  See attached COPYRIGHT file for terms of use.
+
+This specification documents Portable Site Information (PSI). It contains all the information an implementer needs.
+
+1 Introduction
+
+1.1 Definition
+
+PSI is a data model that maps URI-identifiable nodes in a general format. Its elements and attributes each fall under one of five objectives:
+
+1.	Mapping node structure.
+2.	Mapping node relationships.
+3.	Separating shared and unique data.
+4.	Metadata hooks.
+5.	Fine-grained filtering.
+
+1.2 Extending PSI
+
+PSI's data model is compact but remains expressive enough that it can be extended through pure grammar; no changes to the PSI DTD/schema are required. It can be used both for creating PSI content and new functionality.
+
+The core PSI package includes bundled PSI extensions for common applications. PSI users can extend or modify these extensions or create new ones. Possible PSI extensions might include:
+
+1.	Mapping the structure of websites, intranets, and other groupings of networked resources.
+2.	Mapping function calls for dynamic data.
+3.	Mapping common packaging formats, especially if they encrypt, compress, sign, or checksum other files, like RPM, ZIP, TAR, and others.
+4.	Mapping packaging techniques used by different programming languages like JAR. WAR, and others. 
+5.	Handling all MIME types.
+6.	Database storage and retrieval.
+7.	Interfacing with all major filesystems.
+8.	Conversion to/from data formats/packaging used by different web, content management, and application servers.
+9.	Mapping directory services like LDAP, X.500, or NDS.
+
+1.3 PSI Content Type
+
+The content type of a PSI map is text/xml. 
+
+2 STRUCTURE
+
+2.1 Overview
+
+PSI maps structures by following the URI syntax defined in RFC 2396 (Uniform Resource Identifiers (URI): Generic Syntax). RFC 2396 divides a URI into four components:
+
+<scheme>://<authority><path>?<query> or <scheme://<authority><path>#<fragment>
+
+PSI handles path, fragment, or query components. It does not map scheme and authority components since they are protocol, platform, or application dependent.
+
+2.2 The psi element
+
+The psi element is the root of a PSI map.
+
+The psi element must appear one time.
+
+2.2.1 The xmlns attribute
+
+The xmlns attribute defines the namespace used by a PSI map. 
+
+It is recommended that a namespace prefix be used with PSI elements and attributes since the majority of a PSI map may be non-PSI data.
+
+Information about which version of PSI is being used must be learned from a PSI map's namespace.
+
+The psi element requires one xmlns attribute. Its
+value must match the string "http://psilib.sourceforge.net/psi/0.4".
+
+2.2.2 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ ...
+</psi:psi>
+
+2.2.3 Schema Fragment
+
+<element name="psi">
+ <complexType>
+  <sequence>
+   <element ref="collection" minOccurs="0" maxOccurs="unbounded"/>
+  </sequence>
+  <attribute name="xmlns" type="string" fixed="http://psilib.sourceforge.net/psi/0.4"/>
+ </complexType>
+</element>
+
+2.3 The collection element
+
+The collection element maps nodes that can contain other nodes in an infinitely deep series of nestable scopes. Normally it maps infinitely nestable containers like directories, classes, or archives.
+
+The term collection originated in RFC 2518 (HTTP Extensions for Distributed Authoring -- WEBDAV):
+
+In a path component, nestable scopes like bar in http://foo/bar/spam are separated by backslashes. RFC 2518 defines each of these scopes as a collection:
+
+The collection element may appear one or more times. It must be a child of the psi element or itself.
+
+2.3.1 The id attribute
+
+The id attribute is a globally unique identifier for a node.
+
+The use of the id attribute in PSI is similar to how it is used in XML grammars like XML Schema and HTML.
+
+A collection element may have one id attribute. Its value must be a string that is globally unique within a PSI map.
+
+This definition applies to other uses of the id attribute in this specification. This specification will detail these other uses if their definition differs substantially from this definition.
+
+2.3.2 The xid attribute
+
+The xid attribute, short for "extensible identifier", is a node identifier that is only guaranteed to be unique among a node's immediate siblings. It is used primarily for data generated or stored in a fixed pattern, where the same set of identifiers are reused several times in the same PSI map under parent nodes with different, globally unique identifiers.
+
+A collection element may have one xid attribute. Its value must be a string.
+
+This definition applies to other uses of the xid attribute in this specification. This specification will detail these other uses if their definition differs substantially from this definition.
+
+
+2.3.3 The class attribute
+
+The class attribute is a reference from one node to another node whose characteristics the first node can inherit.
+
+The use of the class attribute in PSI is similar to its use in HTML.
+
+A collection element may have one class attribute. Its value must be a string that matches another node's id attribute.
+
+This definition will apply to other uses of the class attribute in this specification. This specification will detail these other uses if their definition differs substantially from this definition. 
+
+2.3.4 The xref attribute
+
+The xref attribute, short for "extensible reference", is a reference that can be extended to define a pattern that identifies another node, usually by its xid attribute. This would commonly be a reference like a file path, a regular expression, or an XPath expression.
+
+A collection element may have one xref attribute. Its value must be a string.
+
+This definition will apply to other uses of the xref attribute in this specification. This specification will detail these other uses if their definition differs substantially from this definition.
+
+2.3.5 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.40.1">
+ <psi:collection id="root">
+  ...
+ </psi:collection>
+</psi:psi>
+
+2.3.6 Complex Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.40.1">
+ <psi:collection id="root">
+  <psi:collection id="images">
+   ...
+  </psi:collection>
+  <psi:collection id="scripts">
+   ...
+  </psi:collection>
+   ...
+ </psi:collection>
+ <psi:collection id="root2">
+  ...
+ </psi:collection>
+</psi:psi>
+
+2.3.7 Schema Fragment
+
+<element name="collection">
+ <complexType>
+ <sequence>
+  <element ref="metadata" minOccurs="0"/>
+  <element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
+  <element ref="collection" minOccurs="0" maxOccurs="unbounded"/>
+  <choice minOccurs="0" maxOccurs="unbounded">
+   <element ref="field"/>
+   <element ref="link"/>
+   <element ="include"/>
+   <element ref="resource"/>
+  </choice>
+  </sequence>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="class" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+2.4 The resource element
+
+The resource element maps nodes with one nestable scope that may contain other nodes with one nestable scope. Possible resources might include documents, users, functions, or binaries.
+
+A resource is not allowed to contain infinitely nestable scopes. A collection can; it can have itself as a child while a resource cannot. A resource's nestable scopes are always shallow.
+
+The term resource originated in RFC 2396 where a resource is defined as "anything that has identity". In a URI, the resource is the scope at the very end of a path component, like spam in http://foo/bar/spam.
+
+The resource element can appear zero or more times. It must be a child of the collection element.
+
+2.4.1 The id attribute
+
+The resource element may have one id attribute.
+
+2.4.2 The xid attribute
+
+The resource element may have one xid attribute.
+
+2.4.3 The class attribute
+
+The resource element may have one class attribute.
+
+2.4.4 The xref attribute
+
+The resource element may have one xref attribute.
+
+2.4.5 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="index">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+     <title>Home</title>
+    </head>
+     <body>
+      ...
+     </body>
+   </html> 
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+2.4.6 Complex Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:collection id="images">
+   <psi:resource id="gifs" xref="*.gif">
+    ...
+   </psi:resource>
+   <psi:resource id="jpegs" xref="*.jpeg">
+    ...
+   </psi:resource>
+   ...
+  </psi:collection>
+  <psi:collection id="scripts">
+   <psi:resource id="title-writer" xref="titlewriter.py">
+    ...
+   </psi:resource>
+   <psi:resource id="title-ender" xref="titleender.py">
+    ...
+   </psi:resource>
+  </psi:collection>
+   <psi:resource id="index">
+    <html xmlns="http://www.w3.org/1999/xhtml">
+     <head>
+      <title>Home</title>
+     </head>
+     <body>
+      ...
+     </body>
+   </html>
+  </psi:resource>
+   ...
+ </psi:collection>
+ <psi:collection id="root2">
+  <psi:resource id="index2">
+   <html>
+     <head>
+      <title>Home II</title>
+     </head>
+     <body>
+      ...
+     </body>
+   </html>
+  </psi:resource>
+   ...
+ </psi:collection>
+</psi:psi>
+
+2.4.7 Schema Fragment
+
+<element name="resource">
+ <complexType>
+  <sequence>
+    <element ref="metadatadata" minOccurs="0"/>
+    <element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
+    <choice minOccurs="0" maxOccurs="unbounded">
+     <element ref="field"/>
+     <element ref="link"/>
+     <element ref="include"/>
+     <element ref="text"/>
+     <element ref="fragment"/>
+   </choice>
+   <element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+   <element ref="result" minOccurs="0"/>
+   <element ref="exception" minOccurs="0" maxOccurs="unbounded"/>
+  </sequence>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="class" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+2.5 The fragment element
+
+The fragment element maps nodes with one nestable scope. It normally maps pieces of a resource like HTML anchors, class methods, or arbitrary points within files.
+
+The fragment is the deepest nestable scope in PSI. A fragment, like a resource, is not infinitely nestable. Collections can have other collections as children. A fragment cannot have another fragment as a child. It has one nestable scope. 
+
+The term fragment originated in RFC 2396. In a URI, a fragment is any component inserted after a
+# sign, like guido in http://foo/bar/spam#guido.
+
+The fragment element may appear zero or more times. It must be a child of the resource element.
+
+2.5.1 The id attribute
+
+The fragment element may have one id attribute.
+
+2.5.2 The xid attribute
+
+The fragment element may have one xid attribute.
+
+2.5.3 The class attribute 
+
+The fragment element may have one class attribute.
+
+2.4.4 The xref attribute
+
+The fragment element may have one xref attribute.
+
+2.5.6 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="index">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+     <title>Home</title>
+    </head>
+    <psi:fragment id="body">
+    <body>
+     ...
+    </body>
+   </html>
+   </psi:fragment>
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+2.6 The text element
+
+The text element maps nodes that contain character data, particularly if whitespace preservation is
+significant.
+
+The term text originated in the Document Object Model Recommendation.
+
+The text element can appear zero or more times. It must be a child of the log, resource, fragment,
+param, result, or exception elements. Its content is mixed.
+
+2.6.1 The id attribute
+
+The text element may have one id attribute.
+
+2.6.2 The xid attribute
+
+The text element may have one xid attribute.
+
+2.6.3 The class attribute
+
+The text element may have one class attribute.
+
+2.6.4 The xref attribute
+
+The text element may have one xref attribute.
+
+2.6.5 The xml:space attribute
+ 
+The xml:space attribute is a standard XML attribute that tells a processor if whitespace must be preserved
+or not.
+
+The xml:space attribute is defined in XML 1.0 (Second Edition).
+
+The text element may have one xml:space attribute. The xml:space attribute must have a value matching one of two strings:
+
+2.6.5.1 The default value
+
+The default value indicates that whitespace should be ignored.
+
+2.6.5.2 The preserve value
+
+The preserve value indicates whitespace should be preserved.
+
+2.6.6 Example:
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="README>
+   <psi:text id="README-contents">READ THIS.</psi:text>
+  </psi:resource>
+  <psi:resource id="code">
+   <psi:text id="codeofsomesort" xml:space="preserve">
+    var i=9;
+    var g='add';
+    ...
+   </psi:text>
+  </psi:resource> 
+ </psi:collection>
+</psi:psi>
+
+2.6.7 Schema Fragment
+
+<element name="text">
+  <complexType mixed="true">
+   <attribute name="id" type="ID"/>
+   <attribute name="name" type="string"/>
+
+   <attribute name="class" type="IDREF"/>
+   <attribute name="xref" type="string"/>
+<attribute name="xml:space">
+   <simpleType>
+    <restriction base="NMTOKEN">
+     <enumeration value="default"/>
+     <enumeration value="preserve"/>
+    </restriction>
+   </simpleType>
+  </attribute>
+ </complexType>
+</element>
+
+2.7 The param element
+
+The param element maps arbitrary portions of a query component.
+
+RFC 2396 defines the query component as "a string of information to be interpreted by the resource". Each parameter is a portion of a query to a resource, like van and rossum in http://foo/bar/spam?van+rossum. The resource does something based on the query and either returns a result or raises an exception if something is wrong. 
+
+Parameters may be the contents of either a field, include, link, or text element. A param element may appear zero or more times. It must be a child of the resource or fragment elements.
+
+2.7.1 The id attribute
+
+The param element may have one id attribute.
+
+2.7.2 The xid attribute
+
+The param element may have one xid attribute.
+
+2.7.3 The class attribute
+
+The param element may have one class attribute.
+
+2.7.4 The xref attribute
+
+The param element may have one xref attribute.
+
+2.7.5 The required attribute
+
+The required attribute defines if a parameter must appear for a query to be valid.
+
+The param element must have one required attribute. Its value must match one of three strings:
+
+2.7.5.1 The true value
+
+The true value indicates that a parameter is required.
+
+2.7.5.2 The false value
+
+The false value indicates that a parameter is not required.
+
+2.7.5.3 The optional attribute
+
+The optional value indicates that a parameter is optional.
+
+2.7.6 Schema Fragment
+
+<element name="param">
+ <complexType>
+  <choice>
+   <element name="field" ref="field"/>
+   <element name="link" ref="link"/>
+   <element name="include" ref="include"/>
+   <element name="text" ref="text"/>
+  </choice>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="class" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+  <attribute name="required" use="required">
+  <simpleType>
+   <restriction base="NMTOKEN">
+    <enumeration value="true"/>
+    <enumeration value="false"/>
+    <enumeration value="optional"/>
+   </restriction>
+  </simpleType>
+  </attribute>
+ </complexType>
+</element>
+
+2.8 The result element
+
+The result element maps responses a resource can return after in answer to a query.
+
+Possible results may be the content of either a field, link, include, or text element. The result element may appear one time. It must be a child of the resource or fragment elements.
+
+2.8.1 The id attribute
+
+The result element may have one id attribute.
+
+2.8.2 The xid attribute
+
+The result element may have one xid attribute.
+
+2.8.3 The class attribute
+
+The result element may have one class attribute.
+
+2.8.4 The xref attribute
+
+The result element may have one xref attribute.
+
+2.8.5 Schema Fragment
+
+<element name="result">
+ <complexType>
+  <choice>
+   <element name="field" ref="field"/>
+   <element name="link" ref="link"/>
+   <element name="include" ref="include"/>
+   <element name="text" ref="text"/>
+  </choice>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="class" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+2.9 The exception element
+
+The exception element maps responses a resource can return if a query is invalid.
+
+Possible exceptions may be the content of either a field, link, include, or text element. The exception element may appear zero or more times. It must be a child of the resource or fragment elements.
+
+2.9.1 The id attribute
+
+The result element may have one id attribute.
+
+2.9.2 The xid attribute
+
+The result element may have one xid attribute.
+
+2.9.3 The class attribute
+
+The result element may have one class attribute.
+
+2.9.4 The xref attribute
+
+The result element may have one xref attribute.
+
+2.9.5 Schema Fragment
+
+<element name="exception">
+ <complexType>
+  <choice>
+   <element name="field" ref="field"/>
+   <element name="link" ref="link"/>
+   <element name="include" ref="include"/>
+   <element name="text" ref="text"/>
+  </choice>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="class" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+2.10 Combined Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="index">
+   ...
+   <psi:param id="EnterName">
+    <psi:field id="EnterNameField"/>
+   </psi:param>
+   <psi:param id="EnterEmail">
+    </psi:include ref="FrankEmail"/>
+   </psi:param>
+   <psi:return id="LoginSuccessful">
+    </psi:link ref="DefaultHome"/>
+   </psi:return>
+   <psi:exception id="LoginUnsuccessful">
+    <psi:text id="UnsuccesfulText">
+     Login Unsuccessful. Try again.
+    </psi:text>
+   </psi:exception>
+  </psi:resource>
+  <psi:resource id="DefaultHome">
+   ...
+  </psi:resource>
+  <psi:resource="NameData">
+   ...
+   <psi:text id="Frank" class="EnterNameField">Frank</psi:text>
+   ...
+  </psi:resource>
+  <psi:resource id="EmailData">
+   ...
+   <psi:text id="FrankEmail">frank@frank.com</psi:text>
+    ...
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+3 RELATIONSHIPS
+
+3.1 Overview
+
+Relationships in PSI are mapped with identifiers and references. Any PSI element with a class, xref, or ref attribute can point to another element's id or xid attribute and vice versa. All relationships in PSI are one-to-one; conforming processors must not allow one reference to point to multiple identifiers. The ref attribute maps arbitrary relationships, the class attribute maps inheritance, and the xref attribute maps relationships depending on the context of an expression.
+
+Other relationship mapping grammars like xml:base or XLink can be used with PSI but their role is supplemental. PSI-provided links are largely internal; they only map relationships within PSI. The xref attribute may map relationships outside of PSI depending on the context of the expression it contains.
+
+3.2 The link element
+
+The link element maps a unidirectional reference that acts as a stand-in for an actual node. It would normally map unidirectional links like HTML hrefs, aliases, shortcuts, or UNIX soft links.
+
+The link element can appear zero or more times. It must be a child of the filter, collection, resource, fragment, param, result, or exception elements. Its content is mixed.
+
+3.2.1 The ref attribute
+
+The ref attribute is a reference to the globally unique identifier of the node a link element is standing-in for.
+
+The link element may have one ref attribute. Its value must be a string matching another node's id attribute.
+
+3.2.2 The xref attribute
+
+The xref attribute is a reference containing an pattern that identifies the node a link element is a stand-in for.
+
+The link element may have one xref attribute. Its value must be a string.
+
+3.2.3 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="index">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+     <title>Home</title>
+    </head>
+    <body>
+     <psi:link ref="about"/>About Us</psi:link>
+    </body>
+   </html>
+  </psi:resource>
+  <psi:resource id="about" xref="about.html">
+   ...   
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+3.2.4 Schema Fragment
+
+<element name="link">
+ <complexType mixed="true">
+  <attribute name="ref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+4 DATA SHARING
+
+4.1 Overview.
+
+Data sharing is mapped in PSI by separating data shared by multiple nodes from data unique to one node. Shared data is mapped in nodes that act like templates. Inside a template node, areas between blocks of shared data are mapped as replaceable fields. An outside node's class or xref attribute then references a replaceable field's id or xid attribute within a template node. During use, the node's unique data is inserted at the location of the replaceable field it references. Shared data is inserted around the replaceable field.
+
+4.2 The field element
+
+The field element maps locations inside a node that can be replaced by data from more than one outside source. The use of the field element is similar to the use of format strings (%s) in the Python programming language. This line of Python code:
+
+>>> print "The %s who say %s!" % ("knights", "Ni!")
+
+will result in:
+
+"The knights who say Ni!"
+
+The field element may appear zero or more times. It must be a child of the resource, fragment, param, result, or exception elements.
+
+4.2.1 The id attribute.
+
+The field element may have one id attribute.
+
+4.2.2 The xid attribute
+
+The field element may have one xid attribute.
+
+4.2.3 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="main">
+   ...
+   <p xmlns="http://www.w3.org/1999/xhtml">
+    The <psi:field id="knights"/> who say <psi:field id="ni"/>.
+   </p>
+   ...
+  </psi:resource>
+  <psi:resource id="CapDoc" class="main">
+   <psi:fragment id="CapKnight" class="knights">Knights</psi:fragment>
+   <psi:fragment id="CapNi" class="ni">Ni!</psi:fragment>
+  </psi:resource>
+  <psi:resource id="nocapdoc" class="main">
+   <psi:fragment id="nocapknight" class="knight">knights</psi:fragment>
+   <psi:fragment id="nocapni" class="ni">ni!</psi:fragment>
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+This will result in:
+
+<p>The Knights who say Ni!</p>
+
+when the resource "CapDoc" is processed or:
+
+<p>The knights who say ni!</p>
+
+when the resource "noCapDoc" is processed.
+
+4.2.4 Schema Fragment
+
+<element name="field">
+ <complexType>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+ </complexType>
+</element>
+
+4.3 The include element
+
+The include element maps locations inside a node where data from one other source can be inserted. This maps one-to-one relationships, not one-to-many relationships like the field element.
+
+The include element is the PSI equivalent of xml:include. xml:include can be used for inserting external content into PSI. PSI's include element is strictly internal. It only maps where a node defined in PSI will be inserted into another node defined in PSI.
+
+The include element can appear zero or more times. It must be a child of the resource, fragment, param, result, or exception elements. 
+
+4.3.1 The ref attribute
+
+The ref attribute is a reference to the globally unique identifier of an outside node that will be inserted into a node.
+
+The include element may have one ref attribute. Its value must match the id attribute of another node.
+
+4.3.2 The xref attribute
+
+The xref attribute is a reference containing a pattern that identifies an outside node that will be inserted into a node.
+
+The include element may have one xref attribute. Its value must be a string.
+
+4.3.3 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:resource id="title-picture" match="title.jpeg">
+   ...
+  </psi:resource>
+  <psi:resource id="index">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+     <title>Home</title>
+    </head>
+    <body>
+     <psi:include ref="title-picture"/>
+     ...
+    </body>
+   </html>
+   </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+4.3.4 Schema Fragment
+
+<element name="include">
+ <complexType>
+  <attribute name="ref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+5 METADATA HOOKS
+
+5.1 Overview
+
+In PSI, a node can be described to whatever level of detail desired. PSI provides only the most basic internal metadata. Its handling of metadata is intended to provide little more than hooks for other metadata grammars like RDF/Dublin Core:
+
+5.2 The metadata element
+
+The metadata element is a listing of information about a node.
+
+The use of the metadata element in PSI is similar to its use in SMIL 2.0.
+
+The metadata element may appear once. It must be a child of the collection, fragment, or resource elements.
+
+5.2.1 The state attribute 
+
+The state attribute maps a node's current condition. It could be used to plan how a node will be structured, indicate a resource is locked, or trigger version control.
+
+The metadata element may have one state attribute. Its value must match one of four strings:
+
+5.2.1.1 The planned value
+
+The planned value indicates that this node will be created in the future. This would be used if the basic layout of a node was being laid out but had not been populated with data yet.
+
+5.2.1.2 The readlock value
+
+The readlock value indicates that a node is currently in use and locked against reading or writing. 
+
+5.2.1.3 The writelock value
+
+The writelock value indicates that a node is currently in use and locked against writing.
+
+5.2.1.4 The nolock value 
+
+The nolock value indicates that a node is not being used. 
+
+5.2.2 The ref attribute
+
+The ref attribute is a reference to the globally unique identifier of the outside node currently using a node. This would normally correspond to a a human or computer user mapped as a resource.
+
+The metadata element may have one ref attribute. Its value must be a string matching the id attribute of another
+node.
+
+5.2.3 The xref attribute
+
+The xref attribute is a reference with a pattern that identifies an outside node currently using a node.
+
+ The metadata element may have one xref attribute. Its value must be a string.
+
+5.2.4 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:metadata state="nolock">
+   ...
+  </psi:metadata>
+   ...
+  <psi:resource id="index">
+   <psi:metadata state="writelock" ref="webmaster">
+    ...
+   </psi:metadata>
+    ...
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+5.2.5 Schema Fragment
+
+<element name="metadata">
+ <complexType>
+  <sequence>
+   <element name="log" ref="log" minOccurs="0" maxOccurs="unbounded"/>
+  </sequence>
+  <attribute name="state">
+  <simpleType>
+   <restriction base="NMTOKEN">
+    <enumeration value="planned"/>
+    <enumeration value="readlock"/>
+    <enumeration value="writelock"/>
+    <enumeration value="nolock"/>
+   </restriction>
+  </simpleType>
+  </attribute>
+  <attribute name="idref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+5.3 The log element
+
+The log element is a single record entry in a node's usage history.
+
+The log element may appear zero or more times. It must be a child of the metadata element.
+
+5.3.1 The type attribute 
+
+The type attribute defines what kind of use was recorded. Usually, this was how a node was accessed.
+
+The log element requires one type attribute. Its value must match one of five strings:
+
+5.3.1.1 The read value
+
+The read value indicates the recorded use was a node being accessed by an outside node.
+
+5.3.1.2 The write value
+
+The write value indicates the recorded use was a node being modified by an outside node.
+
+5.3.1.3 The create value
+
+The create value indicates the recorded use was a node being created by an outside node. 
+
+5.3.1.4 The delete value
+
+The delete value indicates the recorded use was a node being removed by an outside node.
+
+5.3.1.6 The acl value
+
+The acl value indicates the recorded use was node having its access permissions modified by an outside node.
+
+5.3.2 The state attribute 
+
+The state attribute records a node's condition at the time the log entry was made.
+
+The log element may have one state attribute. Its value must match one of four strings:
+
+5.3.2.1 The planned value
+
+The planned value indicates that a node was being planned.
+
+5.3.2.2 The readlock value
+
+The readlock value indicates that a node was in use and locked against reading or writing. 
+
+5.3.2.3 The writelock value
+
+The writelock value indicates that a node was in use and locked against writing.
+
+5.3.2.4 The nolock value
+
+The nolock value indicates that a node was not in use.
+
+
+5.3.3 The start attribute 
+
+The start attribute records when use of a node began.
+
+The log element may have one start attribute. Its value must be a string.
+
+5.3.4 The end attribute
+
+The end attribute records when use of a node ended.
+
+The log element may have one end attribute. Its value must be a string.
+
+5.3.5 The ref attribute
+
+The ref attribute identifies which outside node used a node. This normally corresponds to a human user or processor mapped as a PSI resource.
+
+The log element may have one ref attribute. Its value must be a string matching the id attribute of another node.
+
+5.3.6 The xref attribute
+
+The xref attribute is a reference with a pattern that identifies an outside node currently using a node.
+
+ The metadata element may have one xref attribute. Its value must be a string.
+
+5.3.7 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:metadata state="nolock">
+   <psi:log type="read" state="nolock" start="3:30" end="3:31" ref="anyuser">
+    Some user looked at the directory listing.
+   </psi:log>
+   <psi:log type="read" state="nolock" start="3:30" end="3:31" ref="webmaster">
+    The webmaster looked at the directory listing.
+   </psi:log>
+   ...
+  </psi:metadata>
+   ...
+ </psi:collection>
+</psi:psi>
+
+5.3.8 Schema Fragment
+
+<element name="log">
+ <complexType>
+  <sequence>
+   <element name="text" ref="text"/>
+  </sequence>
+  <attribute name="type" use="required">
+   <simpleType>
+    <restriction base="NMTOKEN">
+     <enumeration value="read"/>
+     <enumeration value="write"/>
+     <enumeration value="create"/>
+     <enumeration value="delete"/>
+     <enumeration value="acl"/>
+    </restriction>
+   </simpleType>
+  </attribute>
+  <attribute name="state">
+  <simpleType>
+   <restriction base="NMTOKEN">
+    <enumeration value="planned"/>
+    <enumeration value="readlock"/>
+    <enumeration value="writelock"/>
+    <enumeration value="nolock"/>
+   </restriction>
+  </simpleType>
+  </attribute>
+  <attribute name="start" type="string"/>
+  <attribute name="end" type="string"/>
+  <attribute name="idref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+6 FILTERING
+
+6.1 Overview
+
+PSI allows a series of filters to be applied to any node. This allows fine-grained processing control on large nodes and small. Filters can also reference each other to form filter chains. Each filter contains a series of rules. Many of this rules are conditional statements; if true, the processor does something, if not, it passes on to the next rule. A new rule is needed for each new way a processor should be controlled.
+
+Filters apply to the node they are attached to and all its children. If a rule from a child node's filter conflicts with a rule from a parent node's filter, the child's filter overrides the parent's filter.
+
+A series of link elements can also be inserted under a filter to link to a specific node node should be passed through for processing.
+
+6.2 The filter element
+
+The filter element is a series of rules that control how a node is processed.
+
+The filter element may appear zero or more times. It must be a child of the collection, template, fragment, and resource elements.
+
+6.2.1 The id attribute. 
+
+The filter element may have one id attribute. 
+
+6.2.2 The xid attribute. 
+
+The filter element may have one xid attribute. 
+
+
+6.2.3 The ref attribute
+
+The filter element may have one ref attribute.
+
+The ref attribute usually references the next filter a processor should use if a filter is part of a filter chain.
+
+6.2.4 The xref attribute
+
+The filter element may have one xref attribute.
+
+The xref attribute usually references the next filter a processor should use if a filter is part of a filter chain.
+
+6.2.5 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:filter id="1" ref="2">
+   ...
+  </psi:filter>
+  <psi:resource id="index">
+   <psi:filter id="1" ref="3">
+    ...
+   </psi:filter>
+   <psi:filter id="3">
+    ...
+   </psi:filter>
+    ...
+  </psi:resource>
+ </psi:collection>
+</psi:psi>
+
+6.2.6 Schema Fragment
+
+<element name="filter">
+ <complexType>
+  <sequence>
+   <element name="sort" ref="sort" minOccurs="0" maxOccurs="unbounded"/>
+   <element name="time" ref="time" minOccurs="0" maxOccurs="1"/>
+   <element name="access" ref="access" minOccurs="0" maxOccurs="unbounded"/>
+   <element name="version" ref="version" minOccurs="0" maxOccurs="unbounded"/>
+   <element name="link" ref="link" minOccurs="0" maxOccurs="unbounded"/>
+  </sequence>
+  <attribute name="id" type="ID"/>
+  <attribute name="xid" type="string"/>
+  <attribute name="ref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+6.3 The sort element
+ 
+The sort element maps a rule that controls either a node's order in relationship to other nodes or the order of anything within its scope unless it is overridden locally. This rule can map the order a node occupies in space and time or the order a node and its children are processed in.
+
+The sort element may appear zero or more times. It must be a child of the filter element.
+
+6.3.1 The type attribute
+ 
+The type attribute defines a condition that has to be true for a sort rule to be applied.
+
+The sort element may have one type attribute. Its value must be a string.
+
+6.3.2 The match attribute
+
+The match attribute defines a pattern that has to match the type attribute for a sort rule to be applied.
+
+The sort element may have one match attribute. Its value must be a string.
+
+6.3.3 The action attribute
+
+The action attribute defines what kind of order will be applied to a node and its children.
+
+The sort element requires one action attribute. Its value must match one of seven strings:
+
+6.3.3.1 The none value
+
+The none value indicates that a node and its children have no preset order. 
+
+6.3.3.2 The root value
+
+The root value indicates that a node and its children always come first. 
+
+6.3.3.3 The seq value
+ 
+The seq value indicates that a node and its children will be ordered in sequence. 
+
+6.3.3.4 The choice value
+
+The choice value indicates that a node and its children are alternatives.
+
+6.3.3.5 The par value
+
+The par value indicates that a node and its children parallel other nodes and each other.
+
+6.3.3.6 The pass value
+
+The choice value indicates that a node and its children are excluded from any sorting.
+
+6.3.3.7 The stop value
+
+The stop value indicates that sorting should come to a halt.
+
+6.3.4 The ref attribute
+
+The ref attribute references the globally unique identifier of the node a node should sort itself in relation to.
+
+The sort element may have one ref attribute. Its value must be a string matching another node's id attribute.
+
+6.3.5 The xref attribute
+
+The xref attribute references a pattern that identifies the node a node should sort itself in relation to.
+
+The sort element may have one xref attribute. Its value must be a string.
+
+6.3.6 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:filter id="1" ref="2">
+   <psi:sort action="root"/>
+   ...
+  </psi:filter>
+  <psi:resource id="index">
+   <psi:filter id="1" ref="3">
+    <psi:sort action="root"/>
+    <psi:sort type="user" match="bob" action="choice" ref="index2"/>
+    ...
+   </psi:filter>
+  </psi:resource>
+  <psi:resource id="index2">
+   ...
+  </psi:resource>
+  <psi:resource id="dancingkitties">
+   <psi:filter id="3">
+    <sort action="choice" ref="dancingpuppies"/>
+    ...
+   </psi:filter>
+    ...
+  </psi:resource>
+  <psi:resource id="dancingpuppies">
+   <psi:filter id="4">
+    <psi:sort action="par" ref="dancinghamsters"/>
+   </psi:filter>
+    ...
+  </psi:resource>
+  <psi:resource id="dancinghamsters">
+   <psi:filter id="5">
+    <psi:sort action="seq"/>
+   </psi:filter>
+   <item xmlns="http://www.items.com/items/">...</item>
+   <item>...</item>
+   ...
+  </psi:resource> 
+ </psi:collection>
+</psi:psi>
+
+6.3.7 Schema Fragment
+
+<element name="sort">
+ <complexType>
+  <attribute name="type" type="string"/>
+  <attribute name="match" type="string"/>
+  <attribute name="action">
+  <simpleType>
+   <restriction base="NMTOKEN">
+    <enumeration value="none"/>
+    <enumeration value="root"/>
+    <enumeration value="seq"/>
+    <enumeration value="choice"/>
+    <enumeration value="par"/>
+    <enumeration value="pass"/>
+    <enumeration value="stop"/>
+   </restriction>
+  </simpleType>
+  </attribute>
+  <attribute name="ref" type="IDREF"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+6.4 The time element
+
+The time element is a rule that maps a node's position in time. This rule could map when a node is available, what place it occupies in a sequence of nodes, or when it disappears.
+
+The time element may appear one time. It must be a child of the filter element.
+
+6.4.1 The type attribute
+ 
+The type attribute defines the unit of time a time element uses.
+
+The time element may have one type attribute. Its value must match one of eight strings: 
+
+6.4.1.1 The year value
+
+The year value indicates the unit of time is a year. 
+
+6.4.1.2 The month value
+ 
+The month value indicates the unit of time is a month.
+
+6.4.1.3 The week value 
+
+The week value indicates the unit of time is a week.
+
+6.4.1.4 The day value 
+
+The day value indicates the unit of time is a day.
+
+6.4.1.5 The hour value 
+
+The hour value indicates the unit of time is an hour. 
+
+6.4.1.6 The min value
+
+The min value indicates the unit of time is a minute. 
+
+
+6.4.1.7 The sec value 
+
+The sec value indicates the unit of time is a second. 
+
+6.4.1.8 The mil value
+
+The mil value indicates the unit of time is a millisecond. 
+
+6.4.2 The action attribute
+
+The action attribute defines what happens to a node when its time expires.
+
+The time element may have one action attribute. Its value must match one of four strings:
+
+6.4.2.1 The repeat value
+
+The repeat value indicates that a node should repeat itself in time (how many times is determined by the value of the repeat attribute). 
+
+6.4.2.2 The pause value
+ 
+The repeat value indicates that a node should stop and maintain its state (how long is determined by the value of the pause attribute).  
+
+6.4.2.3 The jump value
+
+The jump value indicates that a processor should jump from this node to to another node upon completion of this nodes time. 
+
+6.4.2.4 The stop value
+ 
+The stop value indicates that a processor should remove a node from the timeline. 
+
+6.4.3 The length attribute
+
+The length attribute sets the number of time units (defined by the type attribute) that measure a node's
+time to live. 
+
+The time element may have one length attribute. Its value must be a string..
+
+6.4.4 The start attribute 
+
+The start attribute sets the exact start time of a node's position in time.
+
+The time element may have one start attribute. Its value must be a string. 
+
+6.4.5 The end attribute
+
+The end attribute sets the exact ending time of a
+node's position in time.
+
+The time element may have one end attribute. Its value must be a string.
+
+6.4.6 The repeat attribute
+
+The repeat attribute sets how many times a node could repeat itself in time.
+
+The time element may have one repeat attribute. Its value must be a string.
+
+6.4.7 The pause attribute
+ 
+The pause attribute defines the time that should elapse between one node's end time and the next node's start time. Can be infinite.
+
+The time element may have one pause attribute. Its value must be a string.
+
+6.4.8 The ref attribute
+
+The ref attribute references the globally unique identifier of the node the processor jumps to after another node's time expires.
+
+The time element may have one ref attribute. Its value must be a string matching another element's id attribute.
+
+6.4.9 The xref attribute
+
+The xref attribute references a pattern that identifies the node the processor jumps to after another node's time expires.
+
+The time element may have one xref attribute. Its value must be a string.
+
+6.4.10 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:filter id="1" ref="2">
+   <psi:sort action="root"/>  
+   ...
+  </psi:filter>
+  <psi:resource id="index">
+   <psi:filter id="1" ref="3">
+    <psi:sort action="root"/>
+    <psi:sort type="user" match="bob" action="choice" ref="index2"/>
+    <psi:time type="month" action="repeat" start="01/01" end="0/2/01" repeat="5"/>
+    ...
+   </psi:filter>
+  </psi:resource>
+  <psi:resource id="index2">
+   ...
+  </psi:resource>
+  <psi:resource id="dancingkitties">
+   <psi:filter id="3">
+    <psi:sort action="choice" ref="dancingpuppies"/>
+    <psi:time type="minute" action="jump" pause="10" ref="index2"/>
+    ...
+   </psi:filter>
+    ...
+  </psi:resource>
+  <psi:resource id="dancingpuppies">
+   <psi:filter id="4">
+    <psi:sort action="para" ref="dancinghamsters"/>
+    <psi:time type="sec" length="10"/>
+   </psi:filter>
+    ...
+  </psi:resource>
+  <psi:resource id="dancinghamsters">
+   <psi:filter id="5">
+    <psi:sort action="seq"/>
+    <psi:time action="stop"/>
+   </psi:filter>
+   <item xmlns="http://www.items.com/items/">...</item>
+   <item>...</item>
+   ...
+  </psi:resource> 
+ </psi:collection>
+</psi:psi>
+
+6.4.11 Schema Fragment
+
+<element name="time">
+ <complexType>
+  <attribute name="type">
+   <simpleType>
+    <restriction base="NMTOKEN">
+     <enumeration value="month"/>
+     <enumeration value="week"/>
+     <enumeration value="day"/>
+     <enumeration value="hour"/>
+     <enumeration value="min"/>
+     <enumeration value="sec"/>
+     <enumeration value="mil"/>
+    </restriction>
+   </simpleType>
+  </attribute>
+  <attribute name="action" use="required">
+   <simpleType>
+    <restriction base="NMTOKEN">
+     <enumeration value="repeat"/>
+     <enumeration value="pause"/>
+     <enumeration value="jump"/>
+     <enumeration value="stop"/>
+    </restriction>
+   </simpleType>
+  </attribute>
+  <attribute name="length" type="string"/>
+  <attribute name="start" type="string"/>
+  <attribute name="end" type="string"/>
+  <attribute name="repeat" type="string"/>
+  <attribute name="pause" type="string"/>
+  <attribute name="ref" type="ref"/>
+  <attribute name="xref" type="string"/>
+ </complexType>
+</element>
+
+6.5 The access element
+
+The access element is a rule that maps how access to a node by an outside node is controlled. If a node represented a user, an access element would reference the id or xid attribute of that node and, based on that, assign it rights. A series of access elements within a filter element forms an access control list.
+
+The access element may appear zero or more times. It must be a child of the filter element.
+ 
+6.5.1 The type attribute
+ 
+The type attribute defines the kind of rights an access element can assign. Most rights can be represented by a combination of the type attribute's values in two or more rules (i.e. permission to copy =write + create).
+
+The access element requires one type attribute. Its value must match one of five strings:
+
+6.5.1.1 The read value
+
+The read value indicates a node may be accessed by an outside node.
+
+6.5.1.2 The write value
+
+The write value indicates a node can be modified by an outside node. 
+
+6.5.1.3 The create value 
+
+The create value indicates that a node may be created by an outside node.  
+
+6.5.1.4 The delete value
+
+The delete value indicates that a node may be removed by an outside node.
+
+6.5.1.5 The acl value
+
+The acl value indicates that a node may have its access permissions modified by an outside node.
+
+6.5.2 The action attribute
+ 
+The action attribute defines if an access right for a node has been granted or denied. 
+
+The access element requires one action attribute. Its value must match one of two strings:
+
+6.5.2.1 The grant value
+
+The grant value indicates that an access right has been granted.
+
+6.5.2.2 The deny value
+
+The deny value indicates that an access right has not been granted.
+
+6.5.3 The auth attribute
+
+The auth attribute defines what kind of authentication or encryption is required to authenticate the node an access rule applies to.
+
+The access element may have one auth attribute. Its value must be a string.
+
+
+6.5.4 The ref attribute
+
+The ref attribute defines what node an access rule applies to by referencing the node's globally unique identifier.
+
+The access element may have one ref attribute. Its value must be a string matching another element's id attribute.
+
+6.5.5 The xref attribute
+
+The xref attribute defines what node an access rule applies to by referencing a pattern that identifies a node.
+
+The access element may have one xref attribute. Its value must be a string.
+
+6.5.6 Example
+
+<psi:psi xmlns:psi="http://psilib.sourceforge.net/psi/0.4">
+ <psi:collection id="root">
+  <psi:filter id="1" ref="2">
+   <psi:sort action="root"/> 
+   <psi:access type="read" action="grant" ref="JoeRandomUser"/>
+   <psi:access type="write" action="deny" ref="JoeRandomUser"/>
+   <psi:access type="create" action="deny" ref="JoeRandomUser"/>
+   <psi:access type="delete" action="deny" ref="JoeRandomUser"/>
+   <psi:access type="acl" action="deny" ref="JoeRandomUser"/>
+   <psi:access type="read" action="grant" ref="Webmaster" auth="MD5"/>
+   <psi:access type="write" action="grant" ref="Webmaster" auth="MD5"/>
+   <psi:access type="create" action="grant" ref="Webmaster" auth="MD5"/>
+   <psi:access type="delete" action="grant" ref="Webmaster" auth="MD5"/>
+   <psi:access type="acl" action="grant" ref="Webmaster" auth="MD5"/>
+    ...
+  </psi:filter>
+  <psi:resource id="UserList">
+   <psi:fragment id="JoeRandomUser">
+    ...
+   </psi:fragment>
+   <psi:fragment id="Webmaster">
+    ...
+   </psi:fragment>
+  </psi:resource>
+   ...
+ </psi:collection>
+</psi:psi>
+
+6.5.7 Schema Fragment
+
+<element name="access">
+ <complexType>
+  <attribute name="type" use="required">
+  <simpleType>
+   <restriction base="NMTOKEN">
+    <enumeration value="read"/>
+    <enumeration value="write"/>
+    <enumeration value="create"/>
+    <enumeration value="delete"/>
+    <enumeration value="acl"/>
+   </restriction>
+  </simpleType>
+  </attribute>
+  <attribute name="action" use="required">