galaxy-dev
  Threads by month 
                
            - ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- 10008 discussions
 
                        
                    14 Sep '09
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/e58e140b89f7
changeset: 2689:e58e140b89f7
user:      Kelly Vincent <kpvincent(a)bx.psu.edu>
date:      Mon Sep 14 14:54:11 2009 -0400
description:
Updated Bowtie wrapper tool to add a number of threads parameter and remove two unnecessary options
2 file(s) affected in this change:
tools/sr_mapping/bowtie_wrapper.py
tools/sr_mapping/bowtie_wrapper.xml
diffs (198 lines):
diff -r 7f4c8fee3b39 -r e58e140b89f7 tools/sr_mapping/bowtie_wrapper.py
--- a/tools/sr_mapping/bowtie_wrapper.py	Mon Sep 14 12:23:16 2009 -0400
+++ b/tools/sr_mapping/bowtie_wrapper.py	Mon Sep 14 14:54:11 2009 -0400
@@ -13,6 +13,7 @@
 def __main__():
     #Parse Command Line
     parser = optparse.OptionParser()
+    parser.add_option('', '--threads', dest='threads', help='The number of threads to run')
     parser.add_option('', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format')
     parser.add_option('', '--input2', dest='input2', help='The reverse reads file in Sanger FASTQ format')
     parser.add_option('', '--output', dest='output', help='The output file')
@@ -35,7 +36,6 @@
     parser.add_option('', '--offbase', dest='offbase', help='Number the first base of a reference sequence as n when outputting alignments')
     parser.add_option('', '--best', dest='best', help="Whether or not to make Bowtie guarantee that reported singleton alignments are 'best' in terms of stratum and in terms of the quality values at the mismatched positions")
     parser.add_option('', '--maxBacktracks', dest='maxBacktracks', help='Maximum number of backtracks permitted when aligning a read')
-    parser.add_option('', '--threadMem', dest='threadMem', help='Number of megabytes of memory a given thread is given to store path descriptors in best mode')
     parser.add_option('', '--strata', dest='strata', help='Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable')
     parser.add_option('', '--minInsert', dest='minInsert', help='Minimum insert size for valid paired-end alignments')
     parser.add_option('', '--maxInsert', dest='maxInsert', help='Maximum insert size for valid paired-end alignments')
@@ -45,7 +45,6 @@
     parser.add_option('', '--reverseAlign', dest='reverseAlign', help='Whether or not to attempt to align the reverse-complement reference strand')
     parser.add_option('', '--phased', dest='phased', help='Whether or not it should alternate between using the forward and mirror indexes in a series of phases so that only half of the index is resident in memory at one time')
     parser.add_option('', '--offrate', dest='offrate', help='Override the offrate of the index to n')
-    parser.add_option('', '--mm', dest='mm', help='Whether or not to use memory-mapped I/O to load the index')
     parser.add_option('', '--seed', dest='seed', help='Seed for pseudo-random number generator')
     parser.add_option('', '--dbkey', dest='dbkey', help='')
     parser.add_option('', '--params', dest='params', help='Whether to use default or specified parameters')
@@ -70,10 +69,10 @@
     if options.genomeSource == 'history':
         # set up commands
         if options.index_settings =='index_pre_set':
-            indexing_cmds = ''
+            indexing_cmds = '--quiet'
         else:
             try:
-                indexing_cmds = '%s %s %s %s %s %s %s --offrate %s %s %s %s %s %s %s' % \
+                indexing_cmds = '%s %s %s %s %s %s %s --offrate %s %s %s %s %s %s %s --quiet' % \
                                 (('','--noauto')[options.iauto_b=='set'], 
                                  ('','--packed')[options.ipacked=='packed'],
                                  ('','--bmax %s'%options.ibmax)[options.ibmax!='None' and options.ibmax>=1], 
@@ -88,7 +87,7 @@
                                  ('','--cutoff %s'%options.icutoff)[int(options.icutoff)>0], 
                                  ('','--oldpmap')[options.ioldpmap=='yes'])
             except ValueError:
-                indexing_cmds = ''
+                indexing_cmds = '--quiet'
                 
         # make temp directory for placement of indices and copy reference file there
         tmp_dir = tempfile.gettempdir()
@@ -97,7 +96,7 @@
         except Exception, erf:
             stop_err('Error creating temp directory for indexing purposes\n' + str(erf))
         options.ref = os.path.join(tmp_dir,os.path.split(options.ref)[1])
-        cmd1 = 'cd %s; bowtie-build %s -f %s %s > /dev/null' % (tmp_dir, indexing_cmds, options.ref, options.ref)
+        cmd1 = 'cd %s; bowtie-build %s -f %s %s' % (tmp_dir, indexing_cmds, options.ref, options.ref)
         try:
             os.system(cmd1)
         except Exception, erf:
@@ -106,11 +105,11 @@
     # set up aligning and generate aligning command options
     # automatically set threads to 8 in both cases
     if options.params == 'pre_set':
-        aligning_cmds = '-p 8'
+        aligning_cmds = '-p %s --quiet' % options.threads
     else:
         try:
             aligning_cmds = '%s %s %s %s %s %s %s %s %s %s %s %s %s %s ' \
-                            '%s %s %s %s %s %s %s %s %s %s %s %s %s %s -p 8' % \
+                            '%s %s %s %s %s %s %s %s %s %s %s %s -p %s --quiet' % \
                             (('','-s %s'%options.skip)[options.skip!='None'], 
                              ('','-u %s'%options.alignLimit)[int(options.alignLimit)>0],
                              ('','-5 %s'%options.trimH)[int(options.trimH)>=0], 
@@ -128,7 +127,6 @@
                              ('','--norc')[options.reverseAlign=='noReverse'],
                              ('','--maxbts %s'%options.maxBacktracks)[options.maxBacktracks!='None' and (options.mismatchSeed=='2' or options.mismatchSeed=='3')], 
                              ('','-y')[options.tryHard=='doTryHard'],
-                             ('','--chunkmbs %s'%options.threadMem)[options.threadMem!='None' and int(options.threadMem)>=0],
                              ('','-k %s'%options.valAlign)[options.valAlign!='None' and int(options.valAlign)>=0], 
                              ('','-a')[options.allValAligns=='doAllValAligns' and int(options.allValAligns)>=0],
                              ('','-m %s'%options.suppressAlign)[int(options.suppressAlign)>=0], 
@@ -137,18 +135,18 @@
                              ('','-B %s'%options.offbase)[int(options.offbase)>=0],
                              ('','-z %s'%options.phased)[options.phased!='None'], 
                              ('','-o %s'%options.offrate)[int(options.offrate)>=0],
-                             ('','--mm')[options.mm=='doMm'], 
-                             ('','--seed %s'%options.seed)[int(options.seed)>=0])
+                             ('','--seed %s'%options.seed)[int(options.seed)>=0],
+                             options.threads)
         except ValueError:
-            aligning_cmds = '-p 8' 
+            aligning_cmds = '-p %s --quiet' % options.threads 
 
     tmp_out = tempfile.NamedTemporaryFile()
 
     # prepare actual aligning commands
     if options.paired == 'paired':
-        cmd2 = 'bowtie %s %s -1 %s -2 %s > %s 2> /dev/null' % (aligning_cmds, options.ref, options.input1, options.input2, tmp_out.name)
+        cmd2 = 'bowtie %s %s -1 %s -2 %s > %s' % (aligning_cmds, options.ref, options.input1, options.input2, tmp_out.name)
     else:
-        cmd2 = 'bowtie %s %s %s > %s 2> /dev/null' % (aligning_cmds, options.ref, options.input1, tmp_out.name)
+        cmd2 = 'bowtie %s %s %s > %s' % (aligning_cmds, options.ref, options.input1, tmp_out.name)
     # prepare command to convert bowtie output to sam and alternative
     cmd3 = 'bowtie2sam.pl %s > %s' % (tmp_out.name, options.output)
     cmd4 = 'cp %s %s' % (tmp_out.name, options.output)
diff -r 7f4c8fee3b39 -r e58e140b89f7 tools/sr_mapping/bowtie_wrapper.xml
--- a/tools/sr_mapping/bowtie_wrapper.xml	Mon Sep 14 12:23:16 2009 -0400
+++ b/tools/sr_mapping/bowtie_wrapper.xml	Mon Sep 14 14:54:11 2009 -0400
@@ -2,6 +2,7 @@
   <description> fast alignment of reads against reference sequence </description>
   <command interpreter="python">
     bowtie_wrapper.py 
+    --threads="8"
     --input1=$singlePaired.input1
     #if $singlePaired.sPaired == "paired":
      --input2=$singlePaired.input2
@@ -33,17 +34,14 @@
      --suppressAlign=$singlePaired.params.suppressAlign
      --offbase=$singlePaired.params.offbase
      --offrate=$singlePaired.params.offrate
-     --mm=$singlePaired.params.mm
      --seed=$singlePaired.params.seed
      --best=$singlePaired.params.bestOption.best
      #if $singlePaired.params.bestOption.best == "doBest":
       --maxBacktracks=$singlePaired.params.bestOption.maxBacktracks
-      --threadMem=$singlePaired.params.bestOption.threadMem
       --strata=$singlePaired.params.bestOption.strata
       --phased="None"
      #else:
       --maxBacktracks="None"
-      --threadMem="None"
       --strata="None"
       #if $singlePaired.sPaired =="single":
        --phased=$singlePaired.params.bestOption.phased
@@ -83,7 +81,6 @@
      --offbase="None"
      --best="None"
      --maxBacktracks="None"
-     --threadMem="None"
      --strata="None"
      --minInsert="None"
      --maxInsert="None"
@@ -93,7 +90,6 @@
      --reverseAlign="None"
      --phased="None"
      --offrate="None"
-     --mm="None"
      --seed="None"
     #end if
     #if $refGenomeSource.genomeSource == "history":
@@ -264,7 +260,6 @@
               </when>
               <when value="doBest">
                 <param name="maxBacktracks" type="integer" value="800" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
-                <param name="threadMem" type="integer" value="32" label="Number of megabytes of memory a given thread is given to store path descriptors in best mode (--chunkmbs)" help="If running in best mode, and you run out of memory, try adjusting this" />
                 <param name="strata" type="select" label="Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable (--strata)">
                   <option value="noStrata">Do not use strata option</option>
                   <option value="doStrata">Use strata option</option>
@@ -272,10 +267,6 @@
               </when>
             </conditional> <!-- bestOption -->
             <param name="offrate" type="integer" value="-1" label="Override the offrate of the index to n (-o)" help="-1 for default" />
-            <param name="mm" type="select" label="Whether or not to use memory-mapped I/O to load the index (--m)">
-              <option value="noMm">Use POSIX/C file I/O</option>
-              <option value="doMm">Use memory-mapped I/O</option>
-            </param>
             <param name="seed" type="integer" value="-1" label="Seed for pseudo-random number generator (--seed)" help="-1 for default" />
           </when> <!-- full -->
         </conditional> <!-- params -->
@@ -339,7 +330,6 @@
               </when>
               <when value="doBest">
                 <param name="maxBacktracks" type="integer" value="800" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
-                <param name="threadMem" type="integer" value="32" label="Number of megabytes of memory a given thread is given to store path descriptors in best mode (--chunkmbs)" help="If running in best mode, and you run out of memory, try adjusting this" />
                 <param name="strata" type="select" label="Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable (--strata)">
                   <option value="noStrata">Do not use strata option</option>
                   <option value="doStrata">Use strata option</option>
@@ -347,10 +337,6 @@
               </when>
             </conditional>
             <param name="offrate" type="integer" value="-1" label="Override the offrate of the index to n -o)" help="-1 for default" />
-            <param name="mm" type="select" label="Whether or not to use memory-mapped I/O to load the index (--mm)">
-              <option value="noMm">Use POSIX/C file I/O</option>
-              <option value="doMm">Use memory-mapped I/O</option>
-            </param>
             <param name="seed" type="integer" value="-1" label="Seed for pseudo-random number generator (--seed)" help="-1 for default" />
           </when> <!-- full -->
         </conditional> <!-- params -->
@@ -431,10 +417,8 @@
       <param name="offbase" value="0" />
       <param name="best" value="doBest" />
       <param name="maxBacktracks" value="800" />
-      <param name="threadMem" value="32" />
       <param name="strata" value="noStrata" />
       <param name="offrate" value="-1" />
-      <param name="mm" value="noMm" />
       <param name="seed" value="403" />
       <output name="output" ftype="sam" file="bowtie_out2.sam" />
     </test>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/7f4c8fee3b39
changeset: 2688:7f4c8fee3b39
user:      Nate Coraor <nate(a)bx.psu.edu>
date:      Mon Sep 14 12:23:16 2009 -0400
description:
Fix path mangling in cleanup_datasets.py
1 file(s) affected in this change:
scripts/cleanup_datasets/cleanup_datasets.py
diffs (23 lines):
diff -r a5ee939839eb -r 7f4c8fee3b39 scripts/cleanup_datasets/cleanup_datasets.py
--- a/scripts/cleanup_datasets/cleanup_datasets.py	Mon Sep 14 12:11:00 2009 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py	Mon Sep 14 12:23:16 2009 -0400
@@ -1,4 +1,8 @@
 #!/usr/bin/env python
+
+new_path = [ os.path.join( os.getcwd(), "lib" ) ]
+new_path.extend( sys.path[1:] ) # remove scripts/ from the path
+sys.path = new_path
 
 from galaxy import eggs
 import pkg_resources  
@@ -8,10 +12,6 @@
 from datetime import datetime, timedelta
 from time import strftime
 from optparse import OptionParser
-
-new_path = [ os.path.join( os.getcwd(), "lib" ) ]
-new_path.extend( sys.path[1:] ) # remove scripts/ from the path
-sys.path = new_path
 
 import galaxy.model.mapping
 from galaxy.model.orm import and_, eagerload
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/a5ee939839eb
changeset: 2687:a5ee939839eb
user:      Nate Coraor <nate(a)bx.psu.edu>
date:      Mon Sep 14 12:11:00 2009 -0400
description:
Remove session stuff from reports webapp
1 file(s) affected in this change:
lib/galaxy/webapps/reports/buildapp.py
diffs (28 lines):
diff -r d301a67eda40 -r a5ee939839eb lib/galaxy/webapps/reports/buildapp.py
--- a/lib/galaxy/webapps/reports/buildapp.py	Mon Sep 14 11:05:36 2009 -0400
+++ b/lib/galaxy/webapps/reports/buildapp.py	Mon Sep 14 12:11:00 2009 -0400
@@ -87,17 +87,6 @@
         from paste import recursive
         app = recursive.RecursiveMiddleware( app, conf )
         log.debug( "Enabling 'recursive' middleware" )
-    ## # Session middleware puts a session factory into the environment 
-    ## if asbool( conf.get( 'use_session', True ) ):
-    ##     store = flup_session.MemorySessionStore()
-    ##     app = flup_session.SessionMiddleware( store, app )
-    ##     log.debug( "Enabling 'flup session' middleware" )
-    # Beaker session middleware
-    if asbool( conf.get( 'use_beaker_session', False ) ):
-        pkg_resources.require( "Beaker" )
-        import beaker.session
-        app = beaker.session.SessionMiddleware( app, conf )
-        log.debug( "Enabling 'beaker session' middleware" )
     # Various debug middleware that can only be turned on if the debug
     # flag is set, either because they are insecure or greatly hurt
     # performance
@@ -185,4 +174,4 @@
         if isinstance( exc_value, AttributeError ) and exc_value.args[0].startswith( "'Undefined' object has no attribute" ):
             return mako.exceptions.html_error_template().render( full=False, css=False )
     formatters.append( mako_html_data )
-    return formatters
\ No newline at end of file
+    return formatters
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    14 Sep '09
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/d301a67eda40
changeset: 2686:d301a67eda40
user:      Greg Von Kuster <greg(a)bx.psu.edu>
date:      Mon Sep 14 11:05:36 2009 -0400
description:
Move the data library admin methods to a separate library_admin controller.
23 file(s) affected in this change:
lib/galaxy/web/controllers/admin.py
lib/galaxy/web/controllers/library_admin.py
templates/admin/index.mako
templates/admin/library/browse_libraries.mako
templates/admin/library/browse_library.mako
templates/admin/library/common.mako
templates/admin/library/folder_info.mako
templates/admin/library/folder_permissions.mako
templates/admin/library/ldda_edit_info.mako
templates/admin/library/ldda_info.mako
templates/admin/library/ldda_permissions.mako
templates/admin/library/library_dataset_info.mako
templates/admin/library/library_dataset_permissions.mako
templates/admin/library/library_info.mako
templates/admin/library/library_permissions.mako
templates/admin/library/new_dataset.mako
templates/admin/library/new_folder.mako
templates/admin/library/new_library.mako
templates/admin/library/select_info_template.mako
templates/admin/requests/show_request.mako
test/base/twilltestcase.py
test/functional/test_forms_and_requests.py
test/functional/test_security_and_libraries.py
diffs (truncated from 3482 to 3000 lines):
diff -r f2af04af3caa -r d301a67eda40 lib/galaxy/web/controllers/admin.py
--- a/lib/galaxy/web/controllers/admin.py	Fri Sep 11 16:09:02 2009 -0400
+++ b/lib/galaxy/web/controllers/admin.py	Mon Sep 14 11:05:36 2009 -0400
@@ -1,15 +1,9 @@
-import shutil, StringIO, operator, urllib, gzip, tempfile, string, sys
+import string, sys
 from datetime import datetime, timedelta
 from galaxy import util, datatypes
 from galaxy.web.base.controller import *
 from galaxy.model.orm import *
 from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
-# Older py compatibility
-try:
-    set()
-except:
-    from sets import Set as set
-
 import logging
 log = logging.getLogger( __name__ )
 
@@ -673,1188 +667,6 @@
                                     out_groups=out_groups,
                                     msg=msg,
                                     messagetype=messagetype )
-
-    # Galaxy Library Stuff
-    @web.expose
-    @web.require_admin
-    def browse_libraries( self, trans, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        return trans.fill_template( '/admin/library/browse_libraries.mako', 
-                                    libraries=trans.app.model.Library.filter( trans.app.model.Library.table.c.deleted==False ) \
-                                                                     .order_by( trans.app.model.Library.name ).all(),
-                                    deleted=False,
-                                    show_deleted=False,
-                                    msg=msg,
-                                    messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def browse_library( self, trans, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        id = params.get( 'id', None )
-        deleted = util.string_as_bool( params.get( 'deleted', False ) )
-        show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
-        if not id:
-            msg = "You must specify a library id."
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_libraries',
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        library = library=trans.app.model.Library.get( id )
-        if not library:
-            msg = "Invalid library id ( %s )."
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_libraries',
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        created_ldda_ids = params.get( 'created_ldda_ids', '' )
-        return trans.fill_template( '/admin/library/browse_library.mako', 
-                                    library=trans.app.model.Library.get( id ),
-                                    deleted=deleted,
-                                    created_ldda_ids=created_ldda_ids,
-                                    forms=get_all_forms( trans, filter=dict(deleted=False) ),
-                                    msg=msg,
-                                    messagetype=messagetype,
-                                    show_deleted=show_deleted )
-    @web.expose
-    @web.require_admin
-    def library( self, trans, id=None, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        if params.get( 'new', False ):
-            action = 'new'
-        elif params.get( 'delete', False ):
-            action = 'delete'
-        elif params.get( 'permissions', False ):
-            action = 'permissions'
-        else:
-            action = 'information'
-        if not id and not action == 'new':
-            msg = "You must specify a library to %s." % action
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_libraries',
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        if not action == 'new':
-            library = trans.app.model.Library.get( int( id ) )
-        if action == 'new':
-            if params.new == 'submitted':
-                library = trans.app.model.Library( name = util.restore_text( params.name ), 
-                                                   description = util.restore_text( params.description ) )
-                root_folder = trans.app.model.LibraryFolder( name = util.restore_text( params.name ), description = "" )
-                root_folder.flush()
-                library.root_folder = root_folder
-                library.flush()
-                msg = "The new library named '%s' has been created" % library.name
-                return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                  action='browse_library',
-                                                                  id=library.id,
-                                                                  msg=util.sanitize_text( msg ),
-                                                                  messagetype='done' ) )
-            return trans.fill_template( '/admin/library/new_library.mako', msg=msg, messagetype=messagetype )
-        elif action == 'information':
-            # See if we have any associated templates
-            info_association = library.get_info_association()
-            if info_association:
-                template = info_association.template
-                # See if we have any field contents
-                info = info_association.info
-                if info:
-                    widgets = get_form_widgets( trans, template, info.content )
-                else:
-                    widgets = get_form_widgets( trans, template )
-            else:
-                widgets = []
-            if params.get( 'rename_library_button', False ):
-                old_name = library.name
-                new_name = util.restore_text( params.name )
-                new_description = util.restore_text( params.description )
-                if not new_name:
-                    msg = 'Enter a valid name'
-                    return trans.fill_template( '/admin/library/library_info.mako',
-                                                library=library,
-                                                widgets=widgets,
-                                                msg=msg,
-                                                messagetype='error' )
-                else:
-                    library.name = new_name
-                    library.description = new_description
-                    library.flush()
-                    # Rename the root_folder
-                    library.root_folder.name = new_name
-                    library.root_folder.description = new_description
-                    library.root_folder.flush()
-                    msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name )
-                    return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                      action='library',
-                                                                      id=id,
-                                                                      edit_info=True,
-                                                                      msg=util.sanitize_text( msg ),
-                                                                      messagetype='done' ) )
-            return trans.fill_template( '/admin/library/library_info.mako',
-                                        library=library,
-                                        widgets=widgets,
-                                        msg=msg,
-                                        messagetype=messagetype )
-        elif action == 'delete':
-            def delete_folder( library_folder ):
-                library_folder.refresh()
-                for folder in library_folder.folders:
-                    delete_folder( folder )
-                for library_dataset in library_folder.datasets:
-                    library_dataset.refresh()
-                    ldda = library_dataset.library_dataset_dataset_association
-                    if ldda:
-                        ldda.refresh()
-                        # We don't set ldda.dataset.deleted to True here because the cleanup_dataset script
-                        # will eventually remove it from disk.  The purge_library method below sets the dataset
-                        # to deleted.  This allows for the library to be undeleted ( before it is purged ), 
-                        # restoring all of its contents.
-                        ldda.deleted = True
-                        ldda.flush()
-                    library_dataset.deleted = True
-                    library_dataset.flush()
-                library_folder.deleted = True
-                library_folder.flush()
-            library.refresh()
-            delete_folder( library.root_folder )
-            library.deleted = True
-            library.flush()
-            msg = "Library '%s' and all of its contents have been marked deleted" % library.name
-            return trans.response.send_redirect( web.url_for( action='browse_libraries', msg=util.sanitize_text( msg ), messagetype='done' ) )
-        elif action == 'permissions':
-            if params.get( 'update_roles_button', False ):
-                # The user clicked the Save button on the 'Associate With Roles' form
-                permissions = {}
-                for k, v in trans.app.model.Library.permitted_actions.items():
-                    in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
-                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                trans.app.security_agent.set_all_library_permissions( library, permissions )
-                library.refresh()
-                # Copy the permissions to the root folder
-                trans.app.security_agent.copy_library_permissions( library, library.root_folder )
-                msg = "Permissions updated for library '%s'" % library.name
-                return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                  action='library',
-                                                                  id=id,
-                                                                  permissions=True,
-                                                                  msg=util.sanitize_text( msg ),
-                                                                  messagetype='done' ) )
-            return trans.fill_template( '/admin/library/library_permissions.mako',
-                                        library=library,
-                                        msg=msg,
-                                        messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def deleted_libraries( self, trans, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        libraries=trans.app.model.Library.filter( and_( trans.app.model.Library.table.c.deleted==True,
-                                                        trans.app.model.Library.table.c.purged==False ) ) \
-                                         .order_by( trans.app.model.Library.table.c.name ).all()
-        return trans.fill_template( '/admin/library/browse_libraries.mako', 
-                                    libraries=libraries,
-                                    deleted=True,
-                                    msg=msg,
-                                    messagetype=messagetype,
-                                    show_deleted=True )
-    @web.expose
-    @web.require_admin
-    def purge_library( self, trans, **kwd ):
-        params = util.Params( kwd )
-        library = trans.app.model.Library.get( int( params.id ) )
-        def purge_folder( library_folder ):
-            for lf in library_folder.folders:
-                purge_folder( lf )
-            library_folder.refresh()
-            for library_dataset in library_folder.datasets:
-                library_dataset.refresh()
-                ldda = library_dataset.library_dataset_dataset_association
-                if ldda:
-                    ldda.refresh()
-                    dataset = ldda.dataset
-                    dataset.refresh()
-                    # If the dataset is not associated with any additional undeleted folders, then we can delete it.
-                    # We don't set dataset.purged to True here because the cleanup_datasets script will do that for
-                    # us, as well as removing the file from disk.
-                    #if not dataset.deleted and len( dataset.active_library_associations ) <= 1: # This is our current ldda
-                    dataset.deleted = True
-                    dataset.flush()
-                    ldda.deleted = True
-                    ldda.flush()
-                library_dataset.deleted = True
-                library_dataset.flush()
-            library_folder.deleted = True
-            library_folder.purged = True
-            library_folder.flush()
-        if not library.deleted:
-            msg = "Library '%s' has not been marked deleted, so it cannot be purged" % ( library.name )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_libraries',
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        else:
-            purge_folder( library.root_folder )
-            library.purged = True
-            library.flush()
-            msg = "Library '%s' and all of its contents have been purged, datasets will be removed from disk via the cleanup_datasets script" % library.name
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='deleted_libraries',
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='done' ) )
-    @web.expose
-    @web.require_admin
-    def folder( self, trans, id, library_id, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )            
-        if params.get( 'new', False ):
-            action = 'new'
-        elif params.get( 'delete', False ):
-            action = 'delete'
-        elif params.get( 'permissions', False ):
-            action = 'permissions'
-        else:
-            # 'information' will be the default
-            action = 'information'
-        folder = trans.app.model.LibraryFolder.get( int( id ) )
-        if not folder:
-            msg = "Invalid folder specified, id: %s" % str( id )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        if action == 'new':
-            if params.new == 'submitted':
-                new_folder = trans.app.model.LibraryFolder( name=util.restore_text( params.name ),
-                                                            description=util.restore_text( params.description ) )
-                # We are associating the last used genome build with folders, so we will always
-                # initialize a new folder with the first dbkey in util.dbnames which is currently
-                # ?    unspecified (?)
-                new_folder.genome_build = util.dbnames.default_value
-                folder.add_folder( new_folder )
-                new_folder.flush()
-                # New folders default to having the same permissions as their parent folder
-                trans.app.security_agent.copy_library_permissions( folder, new_folder )
-                msg = "New folder named '%s' has been added to the library" % new_folder.name
-                return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                  action='browse_library',
-                                                                  id=library_id,
-                                                                  msg=util.sanitize_text( msg ),
-                                                                  messagetype='done' ) )
-            return trans.fill_template( '/admin/library/new_folder.mako',
-                                        library_id=library_id,
-                                        folder=folder,
-                                        msg=msg,
-                                        messagetype=messagetype )
-        elif action == 'information':
-            # See if we have any associated templates
-            info_association = folder.get_info_association()
-            if info_association:
-                template = info_association.template
-                # See if we have any field contents
-                info = info_association.info
-                if info:
-                    widgets = get_form_widgets( trans, template, info.content )
-                else:
-                    widgets = get_form_widgets( trans, template )
-            else:
-                widgets = []
-            if params.get( 'rename_folder_button', False ):
-                old_name = folder.name
-                new_name = util.restore_text( params.name )
-                new_description = util.restore_text( params.description )
-                if not new_name:
-                    msg = 'Enter a valid name'
-                    return trans.fill_template( '/admin/library/folder_info.mako',
-                                                folder=folder,
-                                                library_id=library_id,
-                                                widgets=widgets,
-                                                msg=msg,
-                                                messagetype='error' )
-                else:
-                    folder.name = new_name
-                    folder.description = new_description
-                    folder.flush()
-                    msg = "Folder '%s' has been renamed to '%s'" % ( old_name, new_name )
-                    return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                      action='folder',
-                                                                      id=id,
-                                                                      library_id=library_id,
-                                                                      edit_info=True,
-                                                                      msg=util.sanitize_text( msg ),
-                                                                      messagetype='done' ) )
-            return trans.fill_template( '/admin/library/folder_info.mako',
-                                        folder=folder,
-                                        library_id=library_id,
-                                        widgets=widgets,
-                                        msg=msg,
-                                        messagetype=messagetype )
-        elif action == 'delete':
-            folder.deleted = True
-            folder.flush()
-            msg = "Folder '%s' and all of its contents have been marked deleted" % folder.name
-            return trans.response.send_redirect( web.url_for( action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='done' ) )
-        elif action =='permissions':
-            if params.get( 'update_roles_button', False ):
-                # The user clicked the Save button on the 'Associate With Roles' form
-                permissions = {}
-                for k, v in trans.app.model.Library.permitted_actions.items():
-                    in_roles = [ trans.app.model.Role.get( int( x ) ) for x in util.listify( params.get( k + '_in', [] ) ) ]
-                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                trans.app.security_agent.set_all_library_permissions( folder, permissions )
-                folder.refresh()
-                msg = "Permissions updated for folder '%s'" % folder.name
-                return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                  action='folder',
-                                                                  id=id,
-                                                                  library_id=library_id,
-                                                                  permissions=True,
-                                                                  msg=util.sanitize_text( msg ),
-                                                                  messagetype='done' ) )
-            return trans.fill_template( '/admin/library/folder_permissions.mako',
-                                        folder=folder,
-                                        library_id=library_id,
-                                        msg=msg,
-                                        messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def library_dataset( self, trans, id, library_id, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        if params.get( 'permissions', False ):
-            action = 'permissions'
-        else:
-            action = 'information'
-        library_dataset = trans.app.model.LibraryDataset.get( id )
-        if not library_dataset:
-            msg = "Invalid library dataset specified, id: %s" %str( id )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        if action == 'information':
-            if params.get( 'edit_attributes_button', False ):
-                old_name = library_dataset.name
-                new_name = util.restore_text( params.get( 'name', '' ) )
-                new_info = util.restore_text( params.get( 'info', '' ) )
-                if not new_name:
-                    msg = 'Enter a valid name'
-                    messagetype = 'error'
-                else:
-                    library_dataset.name = new_name
-                    library_dataset.info = new_info
-                    library_dataset.flush()
-                    msg = "Dataset '%s' has been renamed to '%s'" % ( old_name, new_name )
-                    messagetype = 'done'
-            return trans.fill_template( '/admin/library/library_dataset_info.mako',
-                                        library_dataset=library_dataset,
-                                        library_id=library_id,
-                                        msg=msg,
-                                        messagetype=messagetype )
-        elif action == 'permissions':
-            if params.get( 'update_roles_button', False ):
-                # The user clicked the Save button on the 'Edit permissions and role associations' form
-                permissions = {}
-                for k, v in trans.app.model.Library.permitted_actions.items():
-                    in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
-                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                # Set the LIBRARY permissions on the LibraryDataset
-                # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
-                trans.app.security_agent.set_all_library_permissions( library_dataset, permissions )
-                library_dataset.refresh()
-                # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
-                trans.app.security_agent.set_all_library_permissions( library_dataset.library_dataset_dataset_association, permissions )
-                library_dataset.library_dataset_dataset_association.refresh()
-                msg = 'Permissions and roles have been updated for library dataset %s' % library_dataset.name
-            return trans.fill_template( '/admin/library/library_dataset_permissions.mako',
-                                        library_dataset=library_dataset,
-                                        library_id=library_id,
-                                        msg=msg,
-                                        messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def library_dataset_dataset_association( self, trans, library_id, folder_id, id=None, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        deleted = util.string_as_bool( params.get( 'deleted', False ) )
-        show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
-        dbkey = params.get( 'dbkey', None )
-        if isinstance( dbkey, list ):
-            last_used_build = dbkey[0]
-        else:
-            last_used_build = dbkey
-        folder = trans.app.model.LibraryFolder.get( folder_id )
-        if folder and last_used_build in [ 'None', None, '?' ]:
-            last_used_build = folder.genome_build
-        replace_id = params.get( 'replace_id', None )
-        if replace_id:
-            replace_dataset = trans.app.model.LibraryDataset.get( int( replace_id ) )
-            if not last_used_build:
-                last_used_build = replace_dataset.library_dataset_dataset_association.dbkey
-        else:
-            replace_dataset = None
-        # Let's not overwrite the imported datatypes module with the variable datatypes?
-        # The built-in 'id' is overwritten in lots of places as well
-        ldatatypes = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ]
-        ldatatypes.sort()
-        if params.get( 'new_dataset_button', False ):
-            upload_option = params.get( 'upload_option', 'upload_file' )
-            created_ldda_ids = trans.webapp.controllers[ 'library_dataset' ].upload_dataset( trans,
-                                                                                             controller='admin',
-                                                                                             library_id=library_id,
-                                                                                             folder_id=folder_id,
-                                                                                             replace_dataset=replace_dataset,
-                                                                                             **kwd )
-            if created_ldda_ids:
-                total_added = len( created_ldda_ids.split( ',' ) )
-                if replace_dataset:
-                    msg = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset.name, folder.name )
-                else:
-                    if not folder.parent:
-                        # Libraries have the same name as their root_folder
-                        msg = "Added %d datasets to the library '%s' ( each is selected ).  " % ( total_added, folder.name )
-                    else:
-                        msg = "Added %d datasets to the folder '%s' ( each is selected ).  " % ( total_added, folder.name )
-                    msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
-                messagetype='done'
-            else:
-                msg = "Upload failed"
-                messagetype='error'
-            trans.response.send_redirect( web.url_for( controller='admin',
-                                                       action='browse_library',
-                                                       id=library_id,
-                                                       created_ldda_ids=created_ldda_ids,
-                                                       msg=util.sanitize_text( msg ),
-                                                       messagetype=messagetype ) )
-        elif not id or replace_dataset:
-            # See if we have any associated templates
-            info_association = folder.get_info_association()
-            if info_association:
-                template = info_association.template
-                widgets = get_form_widgets( trans, template )
-            else:
-                widgets = []
-            upload_option = params.get( 'upload_option', 'upload_file' )
-            # No dataset(s) specified, so display the upload form.  Send list of data formats to the form
-            # so the "extension" select list can be populated dynamically
-            file_formats = trans.app.datatypes_registry.upload_file_formats
-            # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically
-            def get_dbkey_options( last_used_build ):
-                for dbkey, build_name in util.dbnames:
-                    yield build_name, dbkey, ( dbkey==last_used_build )
-            dbkeys = get_dbkey_options( last_used_build )
-            # Send list of roles to the form so the dataset can be associated with 1 or more of them.
-            roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all()
-            # Send the current history to the form to enable importing datasets from history to library
-            history = trans.get_history()
-            history.refresh()
-            return trans.fill_template( '/admin/library/new_dataset.mako',
-                                        upload_option=upload_option,
-                                        library_id=library_id,
-                                        folder_id=folder_id,
-                                        replace_id=replace_id,
-                                        file_formats=file_formats,
-                                        dbkeys=dbkeys,
-                                        last_used_build=last_used_build,
-                                        roles=roles,
-                                        history=history,
-                                        widgets=widgets,
-                                        msg=msg,
-                                        messagetype=messagetype,
-                                        replace_dataset=replace_dataset )
-        else:
-            if params.get( 'permissions', False ):
-                action = 'permissions'
-            elif params.get( 'edit_info', False ):
-                action = 'edit_info'
-            else:
-                action = 'info'
-            if id.count( ',' ):
-                ids = id.split( ',' )
-                id = None
-            else:
-                ids = None
-        if id:
-            # ldda_id specified, display attributes form
-            ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
-            if not ldda:
-                msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id )
-                return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                  action='browse_library',
-                                                                  id=library_id,
-                                                                  msg=util.sanitize_text( msg ),
-                                                                  messagetype='error' ) )
-            # See if we have any associated templates
-            info_association = ldda.get_info_association()
-            if info_association:
-                template = info_association.template
-                # See if we have any field contents
-                info = info_association.info
-                if info:
-                    widgets = get_form_widgets( trans, template, info.content )
-                else:
-                    widgets = get_form_widgets( trans, template )
-            else:
-                widgets = []
-            if action == 'permissions':
-                if params.get( 'update_roles_button', False ):
-                    permissions = {}
-                    accessible = False
-                    for k, v in trans.app.model.Dataset.permitted_actions.items():
-                        # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not
-                        # the DATASET_ACCESS permission, making the former useless.  Need to display a warning message.
-                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ]
-                        # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible
-                        if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
-                            if len( in_roles ) > 1:
-                                # Get the set of all users that are being associated with the dataset
-                                in_roles_set = set()
-                                for role in in_roles:
-                                    in_roles_set.add( role )
-                                users_set = set()
-                                for role in in_roles:
-                                    for ura in role.users:
-                                        users_set.add( ura.user )
-                                # Make sure that at least 1 user has every role being associated with the dataset
-                                for user in users_set:
-                                    user_roles_set = set()
-                                    for ura in user.roles:
-                                        user_roles_set.add( ura.role )
-                                    if in_roles_set.issubset( user_roles_set ):
-                                        accessible = True
-                                        break
-                            else:
-                                accessible = True
-                        if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
-                            # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions
-                            # TODO: keep access permissions as they originally were, rather than automatically making public
-                            permissions[ trans.app.security_agent.get_action( v.action ) ] = []
-                        else:
-                            permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                    # Set the DATASET permissions on the Dataset
-                    trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions )
-                    ldda.dataset.refresh()
-                    permissions = {}
-                    for k, v in trans.app.model.Library.permitted_actions.items():
-                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
-                        permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                    # Set the LIBRARY permissions on the LibraryDataset
-                    # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
-                    trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions )
-                    ldda.library_dataset.refresh()
-                    # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
-                    trans.app.security_agent.set_all_library_permissions( ldda, permissions )
-                    ldda.refresh()
-                    if not accessible:
-                        msg = "At least 1 user must have every role associated with accessing dataset '%s'. " % ldda.name
-                        msg += "The roles you attempted to associate for access would make this dataset inaccessible by everyone, "
-                        msg += "so access permissions were not set.  All other permissions were updated for the dataset."
-                        messagetype = 'error'
-                    else:
-                        msg = "Permissions updated for dataset '%s'" % ldda.name
-                return trans.fill_template( '/admin/library/ldda_permissions.mako',
-                                            ldda=ldda,
-                                            library_id=library_id,
-                                            msg=msg,
-                                            messagetype=messagetype )
-            elif action == 'info':
-                return trans.fill_template( '/admin/library/ldda_info.mako',
-                                            ldda=ldda,
-                                            library_id=library_id,
-                                            deleted=deleted,
-                                            show_deleted=show_deleted,
-                                            widgets=widgets,
-                                            msg=msg,
-                                            messagetype=messagetype )
-            elif action == 'edit_info':
-                if params.get( 'change', False ):
-                    # The user clicked the Save button on the 'Change data type' form
-                    if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change:
-                        trans.app.datatypes_registry.change_datatype( ldda, params.datatype )
-                        trans.app.model.flush()
-                        msg = "Data type changed for library dataset '%s'" % ldda.name
-                        return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
-                                                    ldda=ldda,
-                                                    library_id=library_id,
-                                                    datatypes=ldatatypes,
-                                                    widgets=widgets,
-                                                    msg=msg,
-                                                    messagetype=messagetype )
-                    else:
-                        return trans.show_error_message( "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype ) )
-                elif params.get( 'save', False ):
-                    # The user clicked the Save button on the 'Edit Attributes' form
-                    old_name = ldda.name
-                    new_name = util.restore_text( params.get( 'name', '' ) )
-                    new_info = util.restore_text( params.get( 'info', '' ) )
-                    new_message = util.restore_text( params.get( 'message', '' ) )
-                    if not new_name:
-                        msg = 'Enter a valid name'
-                        messagetype = 'error'
-                    else:
-                        ldda.name = new_name
-                        ldda.info = new_info
-                        ldda.message = new_message
-                        # The following for loop will save all metadata_spec items
-                        for name, spec in ldda.datatype.metadata_spec.items():
-                            if spec.get("readonly"):
-                                continue
-                            optional = params.get( "is_" + name, None )
-                            if optional and optional == 'true':
-                                # optional element... == 'true' actually means it is NOT checked (and therefore ommitted)
-                                setattr( ldda.metadata, name, None )
-                            else:
-                                setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) )
-                        ldda.metadata.dbkey = dbkey
-                        ldda.datatype.after_edit( ldda )
-                        trans.app.model.flush()
-                        msg = 'Attributes updated for library dataset %s' % ldda.name
-                        messagetype = 'done'
-                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
-                                                ldda=ldda,
-                                                library_id=library_id,
-                                                datatypes=ldatatypes,
-                                                widgets=widgets,
-                                                msg=msg,
-                                                messagetype=messagetype )
-                elif params.get( 'detect', False ):
-                    # The user clicked the Auto-detect button on the 'Edit Attributes' form
-                    for name, spec in ldda.datatype.metadata_spec.items():
-                        # We need to be careful about the attributes we are resetting
-                        if name not in [ 'name', 'info', 'dbkey' ]:
-                            if spec.get( 'default' ):
-                                setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) )
-                    ldda.datatype.set_meta( ldda )
-                    ldda.datatype.after_edit( ldda )
-                    trans.app.model.flush()
-                    msg = 'Attributes updated for library dataset %s' % ldda.name
-                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
-                                                ldda=ldda,
-                                                library_id=library_id,
-                                                datatypes=ldatatypes,
-                                                widgets=widgets,
-                                                msg=msg,
-                                                messagetype=messagetype )
-                elif params.get( 'delete', False ):
-                    ldda.deleted = True
-                    ldda.flush()
-                    msg = 'Dataset %s has been removed from this library' % ldda.name
-                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
-                                                ldda=ldda,
-                                                library_id=library_id,
-                                                datatypes=ldatatypes,
-                                                widgets=widgets,
-                                                msg=msg,
-                                                messagetype=messagetype )
-                ldda.datatype.before_edit( ldda )
-                if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey:
-                    # Copy dbkey into metadata, for backwards compatability
-                    # This looks like it does nothing, but getting the dbkey
-                    # returns the metadata dbkey unless it is None, in which
-                    # case it resorts to the old dbkey.  Setting the dbkey
-                    # sets it properly in the metadata
-                    ldda.metadata.dbkey = ldda.dbkey
-                return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
-                                            ldda=ldda,
-                                            library_id=library_id,
-                                            datatypes=ldatatypes,
-                                            widgets=widgets,
-                                            msg=msg,
-                                            messagetype=messagetype )
-        elif ids:
-            # Multiple ids specfied, display permission form, permissions will be updated for all simultaneously.
-            lddas = []
-            for id in [ int( id ) for id in ids ]:
-                ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
-                if ldda is None:
-                    msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id )
-                    trans.response.send_redirect( web.url_for( controller='admin',
-                                                               action='browse_library',
-                                                               id=library_id,
-                                                               msg=util.sanitize_text( msg ),
-                                                               messagetype='error' ) )
-                lddas.append( ldda )
-            if len( lddas ) < 2:
-                msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids )
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action='browse_library',
-                                                           id=library_id,
-                                                           msg=util.sanitize_text( msg ),
-                                                           messagetype='error' ) )
-            if action == 'permissions':
-                if params.get( 'update_roles_button', False ):
-                    permissions = {}
-                    accessible = False
-                    for k, v in trans.app.model.Dataset.permitted_actions.items():
-                        # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not
-                        # the DATASET_ACCESS permission, making the former useless.  Need to display a warning message.
-                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ]
-                        # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible
-                        if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
-                            if len( in_roles ) > 1:
-                                # Get the set of all users that are being associated with the dataset
-                                in_roles_set = set()
-                                for role in in_roles:
-                                    in_roles_set.add( role )
-                                users_set = set()
-                                for role in in_roles:
-                                    for ura in role.users:
-                                        users_set.add( ura.user )
-                                # Make sure that at least 1 user has every role being associated with the dataset
-                                for user in users_set:
-                                    user_roles_set = set()
-                                    for ura in user.roles:
-                                        user_roles_set.add( ura.role )
-                                    if in_roles_set.issubset( user_roles_set ):
-                                        accessible = True
-                                        break
-                            else:
-                                accessible = True
-                        if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
-                            # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions
-                            # TODO: keep access permissions as they originally were, rather than automatically making public
-                            permissions[ trans.app.security_agent.get_action( v.action ) ] = []
-                        else:
-                            permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                    for ldda in lddas:
-                        # Set the DATASET permissions on the Dataset
-                        trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions )
-                        ldda.dataset.refresh()
-                    permissions = {}
-                    for k, v in trans.app.model.Library.permitted_actions.items():
-                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
-                        permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
-                    for ldda in lddas:
-                        # Set the LIBRARY permissions on the LibraryDataset
-                        # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
-                        trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions )
-                        ldda.library_dataset.refresh()
-                        # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
-                        trans.app.security_agent.set_all_library_permissions( ldda, permissions )
-                        ldda.refresh()
-                    if not accessible:
-                        msg = "At least 1 user must have every role associated with accessing these %d datasets. " % len( lddas )
-                        msg += "The roles you attempted to associate for access would make these datasets inaccessible by everyone, "
-                        msg += "so access permissions were not set.  All other permissions were updated for the datasets."
-                        messagetype = 'error'
-                    else:
-                        msg = "Permissions have been updated on %d datasets" % len( lddas )
-                    return trans.fill_template( "/admin/library/ldda_permissions.mako",
-                                                ldda=lddas,
-                                                library_id=library_id,
-                                                msg=msg,
-                                                messagetype=messagetype )
-                # Ensure that the permissions across all library items are identical, otherwise we can't update them together.
-                check_list = []
-                for ldda in lddas:
-                    permissions = []
-                    # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation
-                    # will always be the same as the permissions on the associated LibraryDataset, so we only need to
-                    # check one Library object
-                    for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ):
-                        if library_permission.action not in permissions:
-                            permissions.append( library_permission.action )
-                    for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ):
-                        if dataset_permission.action not in permissions:
-                            permissions.append( dataset_permission.action )
-                    permissions.sort()
-                    if not check_list:
-                        check_list = permissions
-                    if permissions != check_list:
-                        msg = 'The datasets you selected do not have identical permissions, so they can not be updated together'
-                        trans.response.send_redirect( web.url_for( controller='admin',
-                                                                   action='browse_library',
-                                                                   id=library_id,
-                                                                   msg=util.sanitize_text( msg ),
-                                                                   messagetype='error' ) )
-                return trans.fill_template( "/admin/library/ldda_permissions.mako",
-                                            ldda=lddas,
-                                            library_id=library_id,
-                                            msg=msg,
-                                            messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def add_history_datasets_to_library( self, trans, library_id, folder_id, hda_ids='', **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        try:
-            folder = trans.app.model.LibraryFolder.get( int( folder_id ) )
-        except:
-            msg = "Invalid folder id: %s" % str( folder_id )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        replace_id = params.get( 'replace_id', None )
-        if replace_id:
-            replace_dataset = trans.app.model.LibraryDataset.get( replace_id )
-        else:
-            replace_dataset = None
-        # See if the current history is empty
-        history = trans.get_history()
-        history.refresh()
-        if not history.active_datasets:
-            msg = 'Your current history is empty'
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        if params.get( 'add_history_datasets_to_library_button', False ):
-            hda_ids = util.listify( hda_ids )
-            if hda_ids:
-                dataset_names = []
-                created_ldda_ids = ''
-                for hda_id in hda_ids:
-                    hda = trans.app.model.HistoryDatasetAssociation.get( hda_id )
-                    if hda:
-                        ldda = hda.to_library_dataset_dataset_association( target_folder=folder, replace_dataset=replace_dataset )
-                        created_ldda_ids = '%s,%s' % ( created_ldda_ids, str( ldda.id ) )
-                        dataset_names.append( ldda.name )
-                        if not replace_dataset:
-                            # If replace_dataset is None, the Library level permissions will be taken from the folder and applied to the new 
-                            # LDDA and LibraryDataset.
-                            trans.app.security_agent.copy_library_permissions( folder, ldda )
-                            trans.app.security_agent.copy_library_permissions( folder, ldda.library_dataset )
-                        # Permissions must be the same on the LibraryDatasetDatasetAssociation and the associated LibraryDataset
-                        trans.app.security_agent.copy_library_permissions( ldda.library_dataset, ldda )
-                    else:
-                        msg = "The requested HistoryDatasetAssociation id %s is invalid" % str( hda_id )
-                        return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                          action='browse_library',
-                                                                          id=library_id,
-                                                                          msg=util.sanitize_text( msg ),
-                                                                          messagetype='error' ) )
-                if created_ldda_ids:
-                    created_ldda_ids = created_ldda_ids.lstrip( ',' )
-                    ldda_id_list = created_ldda_ids.split( ',' )
-                    total_added = len( ldda_id_list )
-                    if replace_dataset:
-                        msg = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset.name, folder.name )
-                    else:
-                        if not folder.parent:
-                            # Libraries have the same name as their root_folder
-                            msg = "Added %d datasets to the library '%s' ( each is selected ).  " % ( total_added, folder.name )
-                        else:
-                            msg = "Added %d datasets to the folder '%s' ( each is selected ).  " % ( total_added, folder.name )
-                        msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
-                    return trans.response.send_redirect( web.url_for( controller='admin',
-                                                                      action='browse_library',
-                                                                      id=library_id,
-                                                                      created_ldda_ids=created_ldda_ids,
-                                                                      msg=util.sanitize_text( msg ),
-                                                                      messagetype='done' ) )
-            else:
-                msg = 'Select at least one dataset from the list of active datasets in your current history'
-                messagetype = 'error'
-                last_used_build = folder.genome_build
-                upload_option = params.get( 'upload_option', 'import_from_history' )
-                # Send list of data formats to the form so the "extension" select list can be populated dynamically
-                file_formats = trans.app.datatypes_registry.upload_file_formats
-                # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically
-                def get_dbkey_options( last_used_build ):
-                    for dbkey, build_name in util.dbnames:
-                        yield build_name, dbkey, ( dbkey==last_used_build )
-                dbkeys = get_dbkey_options( last_used_build )
-                # Send list of roles to the form so the dataset can be associated with 1 or more of them.
-                roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all()
-                return trans.fill_template( "/admin/library/new_dataset.mako",
-                                            upload_option=upload_option,
-                                            library_id=library_id,
-                                            folder_id=folder_id,
-                                            replace_id=replace_id,
-                                            file_formats=file_formats,
-                                            dbkeys=dbkeys,
-                                            last_used_build=last_used_build,
-                                            roles=roles,
-                                            history=history,
-                                            widgets=widgets,
-                                            msg=msg,
-                                            messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def info_template( self, trans, library_id, id=None, folder_id=None, ldda_id=None, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        if id:
-            library_item = trans.app.model.FormDefinition.get( int( id ) )
-            library_item_desc = 'information template'
-            response_action = 'info_template'
-            response_id = id
-        elif folder_id:
-            library_item = trans.app.model.LibraryFolder.get( int( folder_id ) )
-            library_item_desc = 'folder'
-            response_action = 'folder'
-            response_id = folder_id
-        elif ldda_id:
-            library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_id ) )
-            library_item_desc = 'library dataset'
-            response_action = 'library_dataset_dataset_association'
-            response_id = ldda_id
-        else:
-            library_item = trans.app.model.Library.get( int( library_id ) )
-            library_item_desc = 'library'
-            response_action = 'browse_library'
-            response_id = library_id
-        forms = get_all_forms( trans, filter=dict(deleted=False) )
-        if not forms:
-            msg = "There are no forms on which to base the template, so create a form and "
-            msg += "try again to add the information template to the %s." % library_item_desc
-            trans.response.send_redirect( web.url_for( controller='forms',
-                                                       action='new',
-                                                       new=True,
-                                                       msg=msg,
-                                                       messagetype='done' ) )
-        if params.get( 'add', False ):
-            if params.get( 'add_info_template_button', False ):
-                form = trans.app.model.FormDefinition.get( int( kwd[ 'form_id' ] ) )
-                #fields = list( copy.deepcopy( form.fields ) )
-                form_values = trans.app.model.FormValues( form, [] )
-                form_values.flush()
-                if folder_id:
-                    assoc = trans.app.model.LibraryFolderInfoAssociation( library_item, form, form_values )
-                elif ldda_id:
-                    assoc = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, form, form_values )
-                else:
-                    assoc = trans.app.model.LibraryInfoAssociation( library_item, form, form_values )
-                assoc.flush()
-                msg = 'An information template based on the form "%s" has been added to this %s.' % ( form.name, library_item_desc )
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action=response_action,
-                                                           id=response_id,
-                                                           msg=msg,
-                                                           message_type='done' ) )
-            return trans.fill_template( '/admin/library/select_info_template.mako',
-                                        library_item_name=library_item.name,
-                                        library_item_desc=library_item_desc,
-                                        library_id=library_id,
-                                        folder_id=folder_id,
-                                        ldda_id=ldda_id,
-                                        forms=forms,
-                                        msg=msg,
-                                        messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def edit_template_info( self, trans, library_id, num_widgets, library_item_id=None, library_item_type=None, **kwd ):
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        folder_id = None
-        if library_item_type == 'library':
-            library_item = trans.app.model.Library.get( library_item_id )
-        elif library_item_type == 'library_dataset':
-            library_item = trans.app.model.LibraryDataset.get( library_item_id )
-        elif library_item_type == 'folder':
-            library_item = trans.app.model.LibraryFolder.get( library_item_id )
-        elif library_item_type == 'library_dataset_dataset_association':
-            library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( library_item_id )
-            # This response_action method requires a folder_id
-            folder_id = library_item.library_dataset.folder.id
-        else:
-            msg = "Invalid library item type ( %s ) specified, id ( %s )" % ( str( library_item_type ), str( library_item_id ) )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        # Save updated template field contents
-        field_contents = []
-        for index in range( int( num_widgets ) ):
-            field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), ''  ) ) )
-        if field_contents:
-            # Since information templates are inherited, the template fields can be displayed on the information
-            # page for a folder or library dataset when it has no info_association object.  If the user has added
-            # field contents on an inherited template via a parent's info_association, we'll need to create a new
-            # form_values and info_association for the current object.
-            info_association = library_item.get_info_association( restrict=True )
-            if info_association:
-                template = info_association.template
-                info = info_association.info
-                form_values = trans.app.model.FormValues.get( info.id )
-                # Update existing content only if it has changed
-                if form_values.content != field_contents:
-                    form_values.content = field_contents
-                    form_values.flush()
-            else:
-                # Inherit the next available info_association so we can get the template
-                info_association = library_item.get_info_association()
-                template = info_association.template
-                # Create a new FormValues object
-                form_values = trans.app.model.FormValues( template, field_contents )
-                form_values.flush()
-                # Create a new info_association between the current library item and form_values
-                if library_item_type == 'folder':
-                    info_association = trans.app.model.LibraryFolderInfoAssociation( library_item, template, form_values )
-                    info_association.flush()
-                elif library_item_type == 'library_dataset_dataset_association':
-                    info_association = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, template, form_values )
-                    info_association.flush()
-        msg = 'The information has been updated.'
-        return trans.response.send_redirect( web.url_for( controller='admin',
-                                                          action=library_item_type,
-                                                          id=library_item.id,
-                                                          library_id=library_id,
-                                                          folder_id=folder_id,
-                                                          edit_info=True,
-                                                          msg=util.sanitize_text( msg ),
-                                                          messagetype='done' ) )
-    @web.expose
-    @web.require_admin
-    def download_dataset_from_folder(self, trans, id, library_id=None, **kwd):
-        """Catches the dataset id and displays file contents as directed"""
-        # id must refer to a LibraryDatasetDatasetAssociation object
-        ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
-        if not ldda.dataset:
-            msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( id )
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-        mime = trans.app.datatypes_registry.get_mimetype_by_extension( ldda.extension.lower() )
-        trans.response.set_content_type( mime )
-        fStat = os.stat( ldda.file_name )
-        trans.response.headers[ 'Content-Length' ] = int( fStat.st_size )
-        valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
-        fname = ldda.name
-        fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ]
-        trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( id ), fname )
-        try:
-            return open( ldda.file_name )
-        except: 
-            msg = 'This dataset contains no content'
-            return trans.response.send_redirect( web.url_for( controller='admin',
-                                                              action='browse_library',
-                                                              id=library_id,
-                                                              msg=util.sanitize_text( msg ),
-                                                              messagetype='error' ) )
-    @web.expose
-    @web.require_admin
-    def datasets( self, trans, library_id, **kwd ):
-        # This method is used by the select list labeled "Perform action on selected datasets"
-        # on the admin library browser.
-        params = util.Params( kwd )
-        msg = util.restore_text( params.get( 'msg', ''  ) )
-        messagetype = params.get( 'messagetype', 'done' )
-        if params.get( 'action_on_datasets_button', False ):
-            if not params.ldda_ids:
-                msg = "At least one dataset must be selected for %s" % params.action
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action='browse_library',
-                                                           id=library_id,
-                                                           msg=util.sanitize_text( msg ),
-                                                           messagetype='error' ) )
-            ldda_ids = util.listify( params.ldda_ids )
-            if params.action == 'edit':
-                # We need the folder containing the LibraryDatasetDatasetAssociation(s)
-                ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_ids[0] )
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action='library_dataset_dataset_association',
-                                                           library_id=library_id,
-                                                           folder_id=ldda.library_dataset.folder.id,
-                                                           id=",".join( ldda_ids ),
-                                                           permissions=True,
-                                                           msg=util.sanitize_text( msg ),
-                                                           messagetype=messagetype ) )
-            elif params.action == 'delete':
-                for id in ldda_ids:
-                    ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
-                    ldda.deleted = True
-                    ldda.flush()
-                msg = "The selected datasets have been removed from this library"
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action='browse_library',
-                                                           id=library_id,
-                                                           show_deleted=False,
-                                                           msg=util.sanitize_text( msg ),
-                                                           messagetype='done' ) )
-            else:
-                msg = "Action %s is not yet implemented" % str( params.action )
-                trans.response.send_redirect( web.url_for( controller='admin',
-                                                           action='browse_library',
-                                                           id=library_id,
-                                                           msg=util.sanitize_text( msg ),
-                                                           messagetype='error' ) )
-        else:
-            trans.response.send_redirect( web.url_for( controller='admin',
-                                                       action='browse_library',
-                                                           id=library_id,
-                                                       msg=util.sanitize_text( msg ),
-                                                       messagetype=messagetype ) )
-    @web.expose
-    @web.require_admin
-    def delete_library_item( self, trans, library_id, library_item_id, library_item_type ):
-        # This action will handle deleting all types of library items.  State is saved for libraries and
-        # folders ( i.e., if undeleted, the state of contents of the library or folder will remain, so previously
-        # deleted / purged contents will have the same state ).  When a library or folder has been deleted for
-        # the amount of time defined in the cleanup_datasets.py script, the library or folder and all of its
-        # contents will be purged.  The association between this method and the cleanup_datasets.py script
-        # enables clean maintenance of libraries and library dataset disk files.  This is also why the following
-        # 3 objects, and not any of the associations ( the cleanup_datasets.py scipot handles everything else ).
-        library_item_types = { 'library': trans.app.model.Library,
-                               'folder': trans.app.model.LibraryFolder,
-                               'library_dataset': trans.app.model.LibraryDataset }
-        if library_item_type not in library_item_types:
-            msg = 'Bad library_item_type specified: %s' % str( library_item_type )
-            messagetype = 'error'
-        else:
-            if library_item_type == 'library_dataset':
-                library_item_desc = 'Dataset'
-            else:
-                library_item_desc = library_item_type.capitalize()
-            library_item = library_item_types[ library_item_type ].get( int( library_item_id ) )
-            library_item.deleted = True
-            library_item.flush()
-            msg = util.sanitize_text( "%s '%s' has been marked deleted" % ( library_item_desc, library_item.name ) )
-            messagetype = 'done'
-        if library_item_type == 'library':
-            return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
-        else:
-            return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype )
-    @web.expose
-    @web.require_admin
-    def undelete_library_item( self, trans, library_id, library_item_id, library_item_type ):
-        # This action will handle undeleting all types of library items
-        library_item_types = { 'library': trans.app.model.Library,
-                               'folder': trans.app.model.LibraryFolder,
-                               'library_dataset': trans.app.model.LibraryDataset }
-        if library_item_type not in library_item_types:
-            msg = 'Bad library_item_type specified: %s' % str( library_item_type )
-            messagetype = 'error'
-        else:
-            if library_item_type == 'library_dataset':
-                library_item_desc = 'Dataset'
-            else:
-                library_item_desc = library_item_type.capitalize()
-            library_item = library_item_types[ library_item_type ].get( int( library_item_id ) )
-            if library_item.purged:
-                msg = '%s %s has been purged, so it cannot be undeleted' % ( library_item_desc, library_item.name )
-                messagetype = 'error'
-            else:
-                library_item.deleted = False
-                library_item.flush()
-                msg = util.sanitize_text( "%s '%s' has been marked undeleted" % ( library_item_desc, library_item.name ) )
-                messagetype = 'done'
-        if library_item_type == 'library':
-            return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
-        else:
-            return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype )
     @web.expose
     @web.require_admin
     def memdump( self, trans, ids = 'None', sorts = 'None', pages = 'None', new_id = None, new_sort = None, **kwd ):
diff -r f2af04af3caa -r d301a67eda40 lib/galaxy/web/controllers/library_admin.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/galaxy/web/controllers/library_admin.py	Mon Sep 14 11:05:36 2009 -0400
@@ -0,0 +1,1195 @@
+import sys
+from galaxy import util
+from galaxy.web.base.controller import *
+from galaxy.model.orm import *
+from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
+# Older py compatibility
+try:
+    set()
+except:
+    from sets import Set as set
+
+import logging
+log = logging.getLogger( __name__ )
+
+class LibraryAdmin( BaseController ):
+    @web.expose
+    @web.require_admin
+    def browse_libraries( self, trans, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        return trans.fill_template( '/admin/library/browse_libraries.mako', 
+                                    libraries=trans.app.model.Library.filter( trans.app.model.Library.table.c.deleted==False ) \
+                                                                     .order_by( trans.app.model.Library.name ).all(),
+                                    deleted=False,
+                                    show_deleted=False,
+                                    msg=msg,
+                                    messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def browse_library( self, trans, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        id = params.get( 'id', None )
+        deleted = util.string_as_bool( params.get( 'deleted', False ) )
+        show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
+        if not id:
+            msg = "You must specify a library id."
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_libraries',
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        library = library=trans.app.model.Library.get( id )
+        if not library:
+            msg = "Invalid library id ( %s )."
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_libraries',
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        created_ldda_ids = params.get( 'created_ldda_ids', '' )
+        return trans.fill_template( '/admin/library/browse_library.mako', 
+                                    library=trans.app.model.Library.get( id ),
+                                    deleted=deleted,
+                                    created_ldda_ids=created_ldda_ids,
+                                    forms=get_all_forms( trans, filter=dict(deleted=False) ),
+                                    msg=msg,
+                                    messagetype=messagetype,
+                                    show_deleted=show_deleted )
+    @web.expose
+    @web.require_admin
+    def library( self, trans, id=None, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        if params.get( 'new', False ):
+            action = 'new'
+        elif params.get( 'delete', False ):
+            action = 'delete'
+        elif params.get( 'permissions', False ):
+            action = 'permissions'
+        else:
+            action = 'information'
+        if not id and not action == 'new':
+            msg = "You must specify a library to %s." % action
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_libraries',
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        if not action == 'new':
+            library = trans.app.model.Library.get( int( id ) )
+        if action == 'new':
+            if params.new == 'submitted':
+                library = trans.app.model.Library( name = util.restore_text( params.name ), 
+                                                   description = util.restore_text( params.description ) )
+                root_folder = trans.app.model.LibraryFolder( name = util.restore_text( params.name ), description = "" )
+                root_folder.flush()
+                library.root_folder = root_folder
+                library.flush()
+                msg = "The new library named '%s' has been created" % library.name
+                return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                  action='browse_library',
+                                                                  id=library.id,
+                                                                  msg=util.sanitize_text( msg ),
+                                                                  messagetype='done' ) )
+            return trans.fill_template( '/admin/library/new_library.mako', msg=msg, messagetype=messagetype )
+        elif action == 'information':
+            # See if we have any associated templates
+            info_association = library.get_info_association()
+            if info_association:
+                template = info_association.template
+                # See if we have any field contents
+                info = info_association.info
+                if info:
+                    widgets = get_form_widgets( trans, template, info.content )
+                else:
+                    widgets = get_form_widgets( trans, template )
+            else:
+                widgets = []
+            if params.get( 'rename_library_button', False ):
+                old_name = library.name
+                new_name = util.restore_text( params.name )
+                new_description = util.restore_text( params.description )
+                if not new_name:
+                    msg = 'Enter a valid name'
+                    return trans.fill_template( '/admin/library/library_info.mako',
+                                                library=library,
+                                                widgets=widgets,
+                                                msg=msg,
+                                                messagetype='error' )
+                else:
+                    library.name = new_name
+                    library.description = new_description
+                    library.flush()
+                    # Rename the root_folder
+                    library.root_folder.name = new_name
+                    library.root_folder.description = new_description
+                    library.root_folder.flush()
+                    msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name )
+                    return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                      action='library',
+                                                                      id=id,
+                                                                      edit_info=True,
+                                                                      msg=util.sanitize_text( msg ),
+                                                                      messagetype='done' ) )
+            return trans.fill_template( '/admin/library/library_info.mako',
+                                        library=library,
+                                        widgets=widgets,
+                                        msg=msg,
+                                        messagetype=messagetype )
+        elif action == 'delete':
+            def delete_folder( library_folder ):
+                library_folder.refresh()
+                for folder in library_folder.folders:
+                    delete_folder( folder )
+                for library_dataset in library_folder.datasets:
+                    library_dataset.refresh()
+                    ldda = library_dataset.library_dataset_dataset_association
+                    if ldda:
+                        ldda.refresh()
+                        # We don't set ldda.dataset.deleted to True here because the cleanup_dataset script
+                        # will eventually remove it from disk.  The purge_library method below sets the dataset
+                        # to deleted.  This allows for the library to be undeleted ( before it is purged ), 
+                        # restoring all of its contents.
+                        ldda.deleted = True
+                        ldda.flush()
+                    library_dataset.deleted = True
+                    library_dataset.flush()
+                library_folder.deleted = True
+                library_folder.flush()
+            library.refresh()
+            delete_folder( library.root_folder )
+            library.deleted = True
+            library.flush()
+            msg = "Library '%s' and all of its contents have been marked deleted" % library.name
+            return trans.response.send_redirect( web.url_for( action='browse_libraries', msg=util.sanitize_text( msg ), messagetype='done' ) )
+        elif action == 'permissions':
+            if params.get( 'update_roles_button', False ):
+                # The user clicked the Save button on the 'Associate With Roles' form
+                permissions = {}
+                for k, v in trans.app.model.Library.permitted_actions.items():
+                    in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
+                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                trans.app.security_agent.set_all_library_permissions( library, permissions )
+                library.refresh()
+                # Copy the permissions to the root folder
+                trans.app.security_agent.copy_library_permissions( library, library.root_folder )
+                msg = "Permissions updated for library '%s'" % library.name
+                return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                  action='library',
+                                                                  id=id,
+                                                                  permissions=True,
+                                                                  msg=util.sanitize_text( msg ),
+                                                                  messagetype='done' ) )
+            return trans.fill_template( '/admin/library/library_permissions.mako',
+                                        library=library,
+                                        msg=msg,
+                                        messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def deleted_libraries( self, trans, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        libraries=trans.app.model.Library.filter( and_( trans.app.model.Library.table.c.deleted==True,
+                                                        trans.app.model.Library.table.c.purged==False ) ) \
+                                         .order_by( trans.app.model.Library.table.c.name ).all()
+        return trans.fill_template( '/admin/library/browse_libraries.mako', 
+                                    libraries=libraries,
+                                    deleted=True,
+                                    msg=msg,
+                                    messagetype=messagetype,
+                                    show_deleted=True )
+    @web.expose
+    @web.require_admin
+    def purge_library( self, trans, **kwd ):
+        params = util.Params( kwd )
+        library = trans.app.model.Library.get( int( params.id ) )
+        def purge_folder( library_folder ):
+            for lf in library_folder.folders:
+                purge_folder( lf )
+            library_folder.refresh()
+            for library_dataset in library_folder.datasets:
+                library_dataset.refresh()
+                ldda = library_dataset.library_dataset_dataset_association
+                if ldda:
+                    ldda.refresh()
+                    dataset = ldda.dataset
+                    dataset.refresh()
+                    # If the dataset is not associated with any additional undeleted folders, then we can delete it.
+                    # We don't set dataset.purged to True here because the cleanup_datasets script will do that for
+                    # us, as well as removing the file from disk.
+                    #if not dataset.deleted and len( dataset.active_library_associations ) <= 1: # This is our current ldda
+                    dataset.deleted = True
+                    dataset.flush()
+                    ldda.deleted = True
+                    ldda.flush()
+                library_dataset.deleted = True
+                library_dataset.flush()
+            library_folder.deleted = True
+            library_folder.purged = True
+            library_folder.flush()
+        if not library.deleted:
+            msg = "Library '%s' has not been marked deleted, so it cannot be purged" % ( library.name )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_libraries',
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        else:
+            purge_folder( library.root_folder )
+            library.purged = True
+            library.flush()
+            msg = "Library '%s' and all of its contents have been purged, datasets will be removed from disk via the cleanup_datasets script" % library.name
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='deleted_libraries',
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='done' ) )
+    @web.expose
+    @web.require_admin
+    def folder( self, trans, id, library_id, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )            
+        if params.get( 'new', False ):
+            action = 'new'
+        elif params.get( 'delete', False ):
+            action = 'delete'
+        elif params.get( 'permissions', False ):
+            action = 'permissions'
+        else:
+            # 'information' will be the default
+            action = 'information'
+        folder = trans.app.model.LibraryFolder.get( int( id ) )
+        if not folder:
+            msg = "Invalid folder specified, id: %s" % str( id )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        if action == 'new':
+            if params.new == 'submitted':
+                new_folder = trans.app.model.LibraryFolder( name=util.restore_text( params.name ),
+                                                            description=util.restore_text( params.description ) )
+                # We are associating the last used genome build with folders, so we will always
+                # initialize a new folder with the first dbkey in util.dbnames which is currently
+                # ?    unspecified (?)
+                new_folder.genome_build = util.dbnames.default_value
+                folder.add_folder( new_folder )
+                new_folder.flush()
+                # New folders default to having the same permissions as their parent folder
+                trans.app.security_agent.copy_library_permissions( folder, new_folder )
+                msg = "New folder named '%s' has been added to the library" % new_folder.name
+                return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                  action='browse_library',
+                                                                  id=library_id,
+                                                                  msg=util.sanitize_text( msg ),
+                                                                  messagetype='done' ) )
+            return trans.fill_template( '/admin/library/new_folder.mako',
+                                        library_id=library_id,
+                                        folder=folder,
+                                        msg=msg,
+                                        messagetype=messagetype )
+        elif action == 'information':
+            # See if we have any associated templates
+            info_association = folder.get_info_association()
+            if info_association:
+                template = info_association.template
+                # See if we have any field contents
+                info = info_association.info
+                if info:
+                    widgets = get_form_widgets( trans, template, info.content )
+                else:
+                    widgets = get_form_widgets( trans, template )
+            else:
+                widgets = []
+            if params.get( 'rename_folder_button', False ):
+                old_name = folder.name
+                new_name = util.restore_text( params.name )
+                new_description = util.restore_text( params.description )
+                if not new_name:
+                    msg = 'Enter a valid name'
+                    return trans.fill_template( '/admin/library/folder_info.mako',
+                                                folder=folder,
+                                                library_id=library_id,
+                                                widgets=widgets,
+                                                msg=msg,
+                                                messagetype='error' )
+                else:
+                    folder.name = new_name
+                    folder.description = new_description
+                    folder.flush()
+                    msg = "Folder '%s' has been renamed to '%s'" % ( old_name, new_name )
+                    return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                      action='folder',
+                                                                      id=id,
+                                                                      library_id=library_id,
+                                                                      edit_info=True,
+                                                                      msg=util.sanitize_text( msg ),
+                                                                      messagetype='done' ) )
+            return trans.fill_template( '/admin/library/folder_info.mako',
+                                        folder=folder,
+                                        library_id=library_id,
+                                        widgets=widgets,
+                                        msg=msg,
+                                        messagetype=messagetype )
+        elif action == 'delete':
+            folder.deleted = True
+            folder.flush()
+            msg = "Folder '%s' and all of its contents have been marked deleted" % folder.name
+            return trans.response.send_redirect( web.url_for( action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='done' ) )
+        elif action =='permissions':
+            if params.get( 'update_roles_button', False ):
+                # The user clicked the Save button on the 'Associate With Roles' form
+                permissions = {}
+                for k, v in trans.app.model.Library.permitted_actions.items():
+                    in_roles = [ trans.app.model.Role.get( int( x ) ) for x in util.listify( params.get( k + '_in', [] ) ) ]
+                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                trans.app.security_agent.set_all_library_permissions( folder, permissions )
+                folder.refresh()
+                msg = "Permissions updated for folder '%s'" % folder.name
+                return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                  action='folder',
+                                                                  id=id,
+                                                                  library_id=library_id,
+                                                                  permissions=True,
+                                                                  msg=util.sanitize_text( msg ),
+                                                                  messagetype='done' ) )
+            return trans.fill_template( '/admin/library/folder_permissions.mako',
+                                        folder=folder,
+                                        library_id=library_id,
+                                        msg=msg,
+                                        messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def library_dataset( self, trans, id, library_id, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        if params.get( 'permissions', False ):
+            action = 'permissions'
+        else:
+            action = 'information'
+        library_dataset = trans.app.model.LibraryDataset.get( id )
+        if not library_dataset:
+            msg = "Invalid library dataset specified, id: %s" %str( id )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        if action == 'information':
+            if params.get( 'edit_attributes_button', False ):
+                old_name = library_dataset.name
+                new_name = util.restore_text( params.get( 'name', '' ) )
+                new_info = util.restore_text( params.get( 'info', '' ) )
+                if not new_name:
+                    msg = 'Enter a valid name'
+                    messagetype = 'error'
+                else:
+                    library_dataset.name = new_name
+                    library_dataset.info = new_info
+                    library_dataset.flush()
+                    msg = "Dataset '%s' has been renamed to '%s'" % ( old_name, new_name )
+                    messagetype = 'done'
+            return trans.fill_template( '/admin/library/library_dataset_info.mako',
+                                        library_dataset=library_dataset,
+                                        library_id=library_id,
+                                        msg=msg,
+                                        messagetype=messagetype )
+        elif action == 'permissions':
+            if params.get( 'update_roles_button', False ):
+                # The user clicked the Save button on the 'Edit permissions and role associations' form
+                permissions = {}
+                for k, v in trans.app.model.Library.permitted_actions.items():
+                    in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
+                    permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                # Set the LIBRARY permissions on the LibraryDataset
+                # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
+                trans.app.security_agent.set_all_library_permissions( library_dataset, permissions )
+                library_dataset.refresh()
+                # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
+                trans.app.security_agent.set_all_library_permissions( library_dataset.library_dataset_dataset_association, permissions )
+                library_dataset.library_dataset_dataset_association.refresh()
+                msg = 'Permissions and roles have been updated for library dataset %s' % library_dataset.name
+            return trans.fill_template( '/admin/library/library_dataset_permissions.mako',
+                                        library_dataset=library_dataset,
+                                        library_id=library_id,
+                                        msg=msg,
+                                        messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def library_dataset_dataset_association( self, trans, library_id, folder_id, id=None, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        deleted = util.string_as_bool( params.get( 'deleted', False ) )
+        show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
+        dbkey = params.get( 'dbkey', None )
+        if isinstance( dbkey, list ):
+            last_used_build = dbkey[0]
+        else:
+            last_used_build = dbkey
+        folder = trans.app.model.LibraryFolder.get( folder_id )
+        if folder and last_used_build in [ 'None', None, '?' ]:
+            last_used_build = folder.genome_build
+        replace_id = params.get( 'replace_id', None )
+        if replace_id:
+            replace_dataset = trans.app.model.LibraryDataset.get( int( replace_id ) )
+            if not last_used_build:
+                last_used_build = replace_dataset.library_dataset_dataset_association.dbkey
+        else:
+            replace_dataset = None
+        # Let's not overwrite the imported datatypes module with the variable datatypes?
+        # The built-in 'id' is overwritten in lots of places as well
+        ldatatypes = [ dtype_name for dtype_name, dtype_value in trans.app.datatypes_registry.datatypes_by_extension.iteritems() if dtype_value.allow_datatype_change ]
+        ldatatypes.sort()
+        if params.get( 'new_dataset_button', False ):
+            upload_option = params.get( 'upload_option', 'upload_file' )
+            created_ldda_ids = trans.webapp.controllers[ 'library_dataset' ].upload_dataset( trans,
+                                                                                             controller='library_admin',
+                                                                                             library_id=library_id,
+                                                                                             folder_id=folder_id,
+                                                                                             replace_dataset=replace_dataset,
+                                                                                             **kwd )
+            if created_ldda_ids:
+                total_added = len( created_ldda_ids.split( ',' ) )
+                if replace_dataset:
+                    msg = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset.name, folder.name )
+                else:
+                    if not folder.parent:
+                        # Libraries have the same name as their root_folder
+                        msg = "Added %d datasets to the library '%s' ( each is selected ).  " % ( total_added, folder.name )
+                    else:
+                        msg = "Added %d datasets to the folder '%s' ( each is selected ).  " % ( total_added, folder.name )
+                    msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
+                messagetype='done'
+            else:
+                msg = "Upload failed"
+                messagetype='error'
+            trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                       action='browse_library',
+                                                       id=library_id,
+                                                       created_ldda_ids=created_ldda_ids,
+                                                       msg=util.sanitize_text( msg ),
+                                                       messagetype=messagetype ) )
+        elif not id or replace_dataset:
+            # See if we have any associated templates
+            info_association = folder.get_info_association()
+            if info_association:
+                template = info_association.template
+                widgets = get_form_widgets( trans, template )
+            else:
+                widgets = []
+            upload_option = params.get( 'upload_option', 'upload_file' )
+            # No dataset(s) specified, so display the upload form.  Send list of data formats to the form
+            # so the "extension" select list can be populated dynamically
+            file_formats = trans.app.datatypes_registry.upload_file_formats
+            # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically
+            def get_dbkey_options( last_used_build ):
+                for dbkey, build_name in util.dbnames:
+                    yield build_name, dbkey, ( dbkey==last_used_build )
+            dbkeys = get_dbkey_options( last_used_build )
+            # Send list of roles to the form so the dataset can be associated with 1 or more of them.
+            roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all()
+            # Send the current history to the form to enable importing datasets from history to library
+            history = trans.get_history()
+            history.refresh()
+            return trans.fill_template( '/admin/library/new_dataset.mako',
+                                        upload_option=upload_option,
+                                        library_id=library_id,
+                                        folder_id=folder_id,
+                                        replace_id=replace_id,
+                                        file_formats=file_formats,
+                                        dbkeys=dbkeys,
+                                        last_used_build=last_used_build,
+                                        roles=roles,
+                                        history=history,
+                                        widgets=widgets,
+                                        msg=msg,
+                                        messagetype=messagetype,
+                                        replace_dataset=replace_dataset )
+        else:
+            if params.get( 'permissions', False ):
+                action = 'permissions'
+            elif params.get( 'edit_info', False ):
+                action = 'edit_info'
+            else:
+                action = 'info'
+            if id.count( ',' ):
+                ids = id.split( ',' )
+                id = None
+            else:
+                ids = None
+        if id:
+            # ldda_id specified, display attributes form
+            ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
+            if not ldda:
+                msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id )
+                return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                  action='browse_library',
+                                                                  id=library_id,
+                                                                  msg=util.sanitize_text( msg ),
+                                                                  messagetype='error' ) )
+            # See if we have any associated templates
+            info_association = ldda.get_info_association()
+            if info_association:
+                template = info_association.template
+                # See if we have any field contents
+                info = info_association.info
+                if info:
+                    widgets = get_form_widgets( trans, template, info.content )
+                else:
+                    widgets = get_form_widgets( trans, template )
+            else:
+                widgets = []
+            if action == 'permissions':
+                if params.get( 'update_roles_button', False ):
+                    permissions = {}
+                    accessible = False
+                    for k, v in trans.app.model.Dataset.permitted_actions.items():
+                        # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not
+                        # the DATASET_ACCESS permission, making the former useless.  Need to display a warning message.
+                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ]
+                        # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible
+                        if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
+                            if len( in_roles ) > 1:
+                                # Get the set of all users that are being associated with the dataset
+                                in_roles_set = set()
+                                for role in in_roles:
+                                    in_roles_set.add( role )
+                                users_set = set()
+                                for role in in_roles:
+                                    for ura in role.users:
+                                        users_set.add( ura.user )
+                                # Make sure that at least 1 user has every role being associated with the dataset
+                                for user in users_set:
+                                    user_roles_set = set()
+                                    for ura in user.roles:
+                                        user_roles_set.add( ura.role )
+                                    if in_roles_set.issubset( user_roles_set ):
+                                        accessible = True
+                                        break
+                            else:
+                                accessible = True
+                        if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
+                            # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions
+                            # TODO: keep access permissions as they originally were, rather than automatically making public
+                            permissions[ trans.app.security_agent.get_action( v.action ) ] = []
+                        else:
+                            permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                    # Set the DATASET permissions on the Dataset
+                    trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions )
+                    ldda.dataset.refresh()
+                    permissions = {}
+                    for k, v in trans.app.model.Library.permitted_actions.items():
+                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
+                        permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                    # Set the LIBRARY permissions on the LibraryDataset
+                    # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
+                    trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions )
+                    ldda.library_dataset.refresh()
+                    # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
+                    trans.app.security_agent.set_all_library_permissions( ldda, permissions )
+                    ldda.refresh()
+                    if not accessible:
+                        msg = "At least 1 user must have every role associated with accessing dataset '%s'. " % ldda.name
+                        msg += "The roles you attempted to associate for access would make this dataset inaccessible by everyone, "
+                        msg += "so access permissions were not set.  All other permissions were updated for the dataset."
+                        messagetype = 'error'
+                    else:
+                        msg = "Permissions updated for dataset '%s'" % ldda.name
+                return trans.fill_template( '/admin/library/ldda_permissions.mako',
+                                            ldda=ldda,
+                                            library_id=library_id,
+                                            msg=msg,
+                                            messagetype=messagetype )
+            elif action == 'info':
+                return trans.fill_template( '/admin/library/ldda_info.mako',
+                                            ldda=ldda,
+                                            library_id=library_id,
+                                            deleted=deleted,
+                                            show_deleted=show_deleted,
+                                            widgets=widgets,
+                                            msg=msg,
+                                            messagetype=messagetype )
+            elif action == 'edit_info':
+                if params.get( 'change', False ):
+                    # The user clicked the Save button on the 'Change data type' form
+                    if ldda.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change:
+                        trans.app.datatypes_registry.change_datatype( ldda, params.datatype )
+                        trans.app.model.flush()
+                        msg = "Data type changed for library dataset '%s'" % ldda.name
+                        return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
+                                                    ldda=ldda,
+                                                    library_id=library_id,
+                                                    datatypes=ldatatypes,
+                                                    widgets=widgets,
+                                                    msg=msg,
+                                                    messagetype=messagetype )
+                    else:
+                        return trans.show_error_message( "You are unable to change datatypes in this manner. Changing %s to %s is not allowed." % ( ldda.extension, params.datatype ) )
+                elif params.get( 'save', False ):
+                    # The user clicked the Save button on the 'Edit Attributes' form
+                    old_name = ldda.name
+                    new_name = util.restore_text( params.get( 'name', '' ) )
+                    new_info = util.restore_text( params.get( 'info', '' ) )
+                    new_message = util.restore_text( params.get( 'message', '' ) )
+                    if not new_name:
+                        msg = 'Enter a valid name'
+                        messagetype = 'error'
+                    else:
+                        ldda.name = new_name
+                        ldda.info = new_info
+                        ldda.message = new_message
+                        # The following for loop will save all metadata_spec items
+                        for name, spec in ldda.datatype.metadata_spec.items():
+                            if spec.get("readonly"):
+                                continue
+                            optional = params.get( "is_" + name, None )
+                            if optional and optional == 'true':
+                                # optional element... == 'true' actually means it is NOT checked (and therefore ommitted)
+                                setattr( ldda.metadata, name, None )
+                            else:
+                                setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) )
+                        ldda.metadata.dbkey = dbkey
+                        ldda.datatype.after_edit( ldda )
+                        trans.app.model.flush()
+                        msg = 'Attributes updated for library dataset %s' % ldda.name
+                        messagetype = 'done'
+                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
+                                                ldda=ldda,
+                                                library_id=library_id,
+                                                datatypes=ldatatypes,
+                                                widgets=widgets,
+                                                msg=msg,
+                                                messagetype=messagetype )
+                elif params.get( 'detect', False ):
+                    # The user clicked the Auto-detect button on the 'Edit Attributes' form
+                    for name, spec in ldda.datatype.metadata_spec.items():
+                        # We need to be careful about the attributes we are resetting
+                        if name not in [ 'name', 'info', 'dbkey' ]:
+                            if spec.get( 'default' ):
+                                setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) )
+                    ldda.datatype.set_meta( ldda )
+                    ldda.datatype.after_edit( ldda )
+                    trans.app.model.flush()
+                    msg = 'Attributes updated for library dataset %s' % ldda.name
+                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
+                                                ldda=ldda,
+                                                library_id=library_id,
+                                                datatypes=ldatatypes,
+                                                widgets=widgets,
+                                                msg=msg,
+                                                messagetype=messagetype )
+                elif params.get( 'delete', False ):
+                    ldda.deleted = True
+                    ldda.flush()
+                    msg = 'Dataset %s has been removed from this library' % ldda.name
+                    return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
+                                                ldda=ldda,
+                                                library_id=library_id,
+                                                datatypes=ldatatypes,
+                                                widgets=widgets,
+                                                msg=msg,
+                                                messagetype=messagetype )
+                ldda.datatype.before_edit( ldda )
+                if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey:
+                    # Copy dbkey into metadata, for backwards compatability
+                    # This looks like it does nothing, but getting the dbkey
+                    # returns the metadata dbkey unless it is None, in which
+                    # case it resorts to the old dbkey.  Setting the dbkey
+                    # sets it properly in the metadata
+                    ldda.metadata.dbkey = ldda.dbkey
+                return trans.fill_template( "/admin/library/ldda_edit_info.mako", 
+                                            ldda=ldda,
+                                            library_id=library_id,
+                                            datatypes=ldatatypes,
+                                            widgets=widgets,
+                                            msg=msg,
+                                            messagetype=messagetype )
+        elif ids:
+            # Multiple ids specfied, display permission form, permissions will be updated for all simultaneously.
+            lddas = []
+            for id in [ int( id ) for id in ids ]:
+                ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
+                if ldda is None:
+                    msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id )
+                    trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                               action='browse_library',
+                                                               id=library_id,
+                                                               msg=util.sanitize_text( msg ),
+                                                               messagetype='error' ) )
+                lddas.append( ldda )
+            if len( lddas ) < 2:
+                msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids )
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action='browse_library',
+                                                           id=library_id,
+                                                           msg=util.sanitize_text( msg ),
+                                                           messagetype='error' ) )
+            if action == 'permissions':
+                if params.get( 'update_roles_button', False ):
+                    permissions = {}
+                    accessible = False
+                    for k, v in trans.app.model.Dataset.permitted_actions.items():
+                        # TODO: need to handle case where a user has the DATASET_MANAGE_PERMISSIONS permission, but not
+                        # the DATASET_ACCESS permission, making the former useless.  Need to display a warning message.
+                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ]
+                        # At least 1 user must have every role associated with this dataset, or the dataset is inaccessible
+                        if v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
+                            if len( in_roles ) > 1:
+                                # Get the set of all users that are being associated with the dataset
+                                in_roles_set = set()
+                                for role in in_roles:
+                                    in_roles_set.add( role )
+                                users_set = set()
+                                for role in in_roles:
+                                    for ura in role.users:
+                                        users_set.add( ura.user )
+                                # Make sure that at least 1 user has every role being associated with the dataset
+                                for user in users_set:
+                                    user_roles_set = set()
+                                    for ura in user.roles:
+                                        user_roles_set.add( ura.role )
+                                    if in_roles_set.issubset( user_roles_set ):
+                                        accessible = True
+                                        break
+                            else:
+                                accessible = True
+                        if not accessible and v == trans.app.security_agent.permitted_actions.DATASET_ACCESS:
+                            # Don't set the permissions for DATASET_ACCESS if inaccessbile, but set all other permissions
+                            # TODO: keep access permissions as they originally were, rather than automatically making public
+                            permissions[ trans.app.security_agent.get_action( v.action ) ] = []
+                        else:
+                            permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                    for ldda in lddas:
+                        # Set the DATASET permissions on the Dataset
+                        trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions )
+                        ldda.dataset.refresh()
+                    permissions = {}
+                    for k, v in trans.app.model.Library.permitted_actions.items():
+                        in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ]
+                        permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
+                    for ldda in lddas:
+                        # Set the LIBRARY permissions on the LibraryDataset
+                        # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions
+                        trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions )
+                        ldda.library_dataset.refresh()
+                        # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation
+                        trans.app.security_agent.set_all_library_permissions( ldda, permissions )
+                        ldda.refresh()
+                    if not accessible:
+                        msg = "At least 1 user must have every role associated with accessing these %d datasets. " % len( lddas )
+                        msg += "The roles you attempted to associate for access would make these datasets inaccessible by everyone, "
+                        msg += "so access permissions were not set.  All other permissions were updated for the datasets."
+                        messagetype = 'error'
+                    else:
+                        msg = "Permissions have been updated on %d datasets" % len( lddas )
+                    return trans.fill_template( "/admin/library/ldda_permissions.mako",
+                                                ldda=lddas,
+                                                library_id=library_id,
+                                                msg=msg,
+                                                messagetype=messagetype )
+                # Ensure that the permissions across all library items are identical, otherwise we can't update them together.
+                check_list = []
+                for ldda in lddas:
+                    permissions = []
+                    # Check the library level permissions - the permissions on the LibraryDatasetDatasetAssociation
+                    # will always be the same as the permissions on the associated LibraryDataset, so we only need to
+                    # check one Library object
+                    for library_permission in trans.app.security_agent.get_library_dataset_permissions( ldda.library_dataset ):
+                        if library_permission.action not in permissions:
+                            permissions.append( library_permission.action )
+                    for dataset_permission in trans.app.security_agent.get_dataset_permissions( ldda.dataset ):
+                        if dataset_permission.action not in permissions:
+                            permissions.append( dataset_permission.action )
+                    permissions.sort()
+                    if not check_list:
+                        check_list = permissions
+                    if permissions != check_list:
+                        msg = 'The datasets you selected do not have identical permissions, so they can not be updated together'
+                        trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                   action='browse_library',
+                                                                   id=library_id,
+                                                                   msg=util.sanitize_text( msg ),
+                                                                   messagetype='error' ) )
+                return trans.fill_template( "/admin/library/ldda_permissions.mako",
+                                            ldda=lddas,
+                                            library_id=library_id,
+                                            msg=msg,
+                                            messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def add_history_datasets_to_library( self, trans, library_id, folder_id, hda_ids='', **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        try:
+            folder = trans.app.model.LibraryFolder.get( int( folder_id ) )
+        except:
+            msg = "Invalid folder id: %s" % str( folder_id )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        replace_id = params.get( 'replace_id', None )
+        if replace_id:
+            replace_dataset = trans.app.model.LibraryDataset.get( replace_id )
+        else:
+            replace_dataset = None
+        # See if the current history is empty
+        history = trans.get_history()
+        history.refresh()
+        if not history.active_datasets:
+            msg = 'Your current history is empty'
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        if params.get( 'add_history_datasets_to_library_button', False ):
+            hda_ids = util.listify( hda_ids )
+            if hda_ids:
+                dataset_names = []
+                created_ldda_ids = ''
+                for hda_id in hda_ids:
+                    hda = trans.app.model.HistoryDatasetAssociation.get( hda_id )
+                    if hda:
+                        ldda = hda.to_library_dataset_dataset_association( target_folder=folder, replace_dataset=replace_dataset )
+                        created_ldda_ids = '%s,%s' % ( created_ldda_ids, str( ldda.id ) )
+                        dataset_names.append( ldda.name )
+                        if not replace_dataset:
+                            # If replace_dataset is None, the Library level permissions will be taken from the folder and applied to the new 
+                            # LDDA and LibraryDataset.
+                            trans.app.security_agent.copy_library_permissions( folder, ldda )
+                            trans.app.security_agent.copy_library_permissions( folder, ldda.library_dataset )
+                        # Permissions must be the same on the LibraryDatasetDatasetAssociation and the associated LibraryDataset
+                        trans.app.security_agent.copy_library_permissions( ldda.library_dataset, ldda )
+                    else:
+                        msg = "The requested HistoryDatasetAssociation id %s is invalid" % str( hda_id )
+                        return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                          action='browse_library',
+                                                                          id=library_id,
+                                                                          msg=util.sanitize_text( msg ),
+                                                                          messagetype='error' ) )
+                if created_ldda_ids:
+                    created_ldda_ids = created_ldda_ids.lstrip( ',' )
+                    ldda_id_list = created_ldda_ids.split( ',' )
+                    total_added = len( ldda_id_list )
+                    if replace_dataset:
+                        msg = "Added %d dataset versions to the library dataset '%s' in the folder '%s'." % ( total_added, replace_dataset.name, folder.name )
+                    else:
+                        if not folder.parent:
+                            # Libraries have the same name as their root_folder
+                            msg = "Added %d datasets to the library '%s' ( each is selected ).  " % ( total_added, folder.name )
+                        else:
+                            msg = "Added %d datasets to the folder '%s' ( each is selected ).  " % ( total_added, folder.name )
+                        msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
+                    return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                                      action='browse_library',
+                                                                      id=library_id,
+                                                                      created_ldda_ids=created_ldda_ids,
+                                                                      msg=util.sanitize_text( msg ),
+                                                                      messagetype='done' ) )
+            else:
+                msg = 'Select at least one dataset from the list of active datasets in your current history'
+                messagetype = 'error'
+                last_used_build = folder.genome_build
+                upload_option = params.get( 'upload_option', 'import_from_history' )
+                # Send list of data formats to the form so the "extension" select list can be populated dynamically
+                file_formats = trans.app.datatypes_registry.upload_file_formats
+                # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically
+                def get_dbkey_options( last_used_build ):
+                    for dbkey, build_name in util.dbnames:
+                        yield build_name, dbkey, ( dbkey==last_used_build )
+                dbkeys = get_dbkey_options( last_used_build )
+                # Send list of roles to the form so the dataset can be associated with 1 or more of them.
+                roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all()
+                return trans.fill_template( "/admin/library/new_dataset.mako",
+                                            upload_option=upload_option,
+                                            library_id=library_id,
+                                            folder_id=folder_id,
+                                            replace_id=replace_id,
+                                            file_formats=file_formats,
+                                            dbkeys=dbkeys,
+                                            last_used_build=last_used_build,
+                                            roles=roles,
+                                            history=history,
+                                            widgets=widgets,
+                                            msg=msg,
+                                            messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def info_template( self, trans, library_id, id=None, folder_id=None, ldda_id=None, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        if id:
+            library_item = trans.app.model.FormDefinition.get( int( id ) )
+            library_item_desc = 'information template'
+            response_action = 'info_template'
+            response_id = id
+        elif folder_id:
+            library_item = trans.app.model.LibraryFolder.get( int( folder_id ) )
+            library_item_desc = 'folder'
+            response_action = 'folder'
+            response_id = folder_id
+        elif ldda_id:
+            library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( int( ldda_id ) )
+            library_item_desc = 'library dataset'
+            response_action = 'library_dataset_dataset_association'
+            response_id = ldda_id
+        else:
+            library_item = trans.app.model.Library.get( int( library_id ) )
+            library_item_desc = 'library'
+            response_action = 'browse_library'
+            response_id = library_id
+        forms = get_all_forms( trans, filter=dict(deleted=False) )
+        if not forms:
+            msg = "There are no forms on which to base the template, so create a form and "
+            msg += "try again to add the information template to the %s." % library_item_desc
+            trans.response.send_redirect( web.url_for( controller='forms',
+                                                       action='new',
+                                                       new=True,
+                                                       msg=msg,
+                                                       messagetype='done' ) )
+        if params.get( 'add', False ):
+            if params.get( 'add_info_template_button', False ):
+                form = trans.app.model.FormDefinition.get( int( kwd[ 'form_id' ] ) )
+                #fields = list( copy.deepcopy( form.fields ) )
+                form_values = trans.app.model.FormValues( form, [] )
+                form_values.flush()
+                if folder_id:
+                    assoc = trans.app.model.LibraryFolderInfoAssociation( library_item, form, form_values )
+                elif ldda_id:
+                    assoc = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, form, form_values )
+                else:
+                    assoc = trans.app.model.LibraryInfoAssociation( library_item, form, form_values )
+                assoc.flush()
+                msg = 'An information template based on the form "%s" has been added to this %s.' % ( form.name, library_item_desc )
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action=response_action,
+                                                           id=response_id,
+                                                           msg=msg,
+                                                           message_type='done' ) )
+            return trans.fill_template( '/admin/library/select_info_template.mako',
+                                        library_item_name=library_item.name,
+                                        library_item_desc=library_item_desc,
+                                        library_id=library_id,
+                                        folder_id=folder_id,
+                                        ldda_id=ldda_id,
+                                        forms=forms,
+                                        msg=msg,
+                                        messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def edit_template_info( self, trans, library_id, num_widgets, library_item_id=None, library_item_type=None, **kwd ):
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        folder_id = None
+        if library_item_type == 'library':
+            library_item = trans.app.model.Library.get( library_item_id )
+        elif library_item_type == 'library_dataset':
+            library_item = trans.app.model.LibraryDataset.get( library_item_id )
+        elif library_item_type == 'folder':
+            library_item = trans.app.model.LibraryFolder.get( library_item_id )
+        elif library_item_type == 'library_dataset_dataset_association':
+            library_item = trans.app.model.LibraryDatasetDatasetAssociation.get( library_item_id )
+            # This response_action method requires a folder_id
+            folder_id = library_item.library_dataset.folder.id
+        else:
+            msg = "Invalid library item type ( %s ) specified, id ( %s )" % ( str( library_item_type ), str( library_item_id ) )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        # Save updated template field contents
+        field_contents = []
+        for index in range( int( num_widgets ) ):
+            field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), ''  ) ) )
+        if field_contents:
+            # Since information templates are inherited, the template fields can be displayed on the information
+            # page for a folder or library dataset when it has no info_association object.  If the user has added
+            # field contents on an inherited template via a parent's info_association, we'll need to create a new
+            # form_values and info_association for the current object.
+            info_association = library_item.get_info_association( restrict=True )
+            if info_association:
+                template = info_association.template
+                info = info_association.info
+                form_values = trans.app.model.FormValues.get( info.id )
+                # Update existing content only if it has changed
+                if form_values.content != field_contents:
+                    form_values.content = field_contents
+                    form_values.flush()
+            else:
+                # Inherit the next available info_association so we can get the template
+                info_association = library_item.get_info_association()
+                template = info_association.template
+                # Create a new FormValues object
+                form_values = trans.app.model.FormValues( template, field_contents )
+                form_values.flush()
+                # Create a new info_association between the current library item and form_values
+                if library_item_type == 'folder':
+                    info_association = trans.app.model.LibraryFolderInfoAssociation( library_item, template, form_values )
+                    info_association.flush()
+                elif library_item_type == 'library_dataset_dataset_association':
+                    info_association = trans.app.model.LibraryDatasetDatasetInfoAssociation( library_item, template, form_values )
+                    info_association.flush()
+        msg = 'The information has been updated.'
+        return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                          action=library_item_type,
+                                                          id=library_item.id,
+                                                          library_id=library_id,
+                                                          folder_id=folder_id,
+                                                          edit_info=True,
+                                                          msg=util.sanitize_text( msg ),
+                                                          messagetype='done' ) )
+    @web.expose
+    @web.require_admin
+    def download_dataset_from_folder(self, trans, id, library_id=None, **kwd):
+        """Catches the dataset id and displays file contents as directed"""
+        # id must refer to a LibraryDatasetDatasetAssociation object
+        ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
+        if not ldda.dataset:
+            msg = 'Invalid LibraryDatasetDatasetAssociation id %s received for file downlaod' % str( id )
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+        mime = trans.app.datatypes_registry.get_mimetype_by_extension( ldda.extension.lower() )
+        trans.response.set_content_type( mime )
+        fStat = os.stat( ldda.file_name )
+        trans.response.headers[ 'Content-Length' ] = int( fStat.st_size )
+        valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+        fname = ldda.name
+        fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ]
+        trans.response.headers[ "Content-Disposition" ] = "attachment; filename=GalaxyLibraryDataset-%s-[%s]" % ( str( id ), fname )
+        try:
+            return open( ldda.file_name )
+        except: 
+            msg = 'This dataset contains no content'
+            return trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                              action='browse_library',
+                                                              id=library_id,
+                                                              msg=util.sanitize_text( msg ),
+                                                              messagetype='error' ) )
+    @web.expose
+    @web.require_admin
+    def datasets( self, trans, library_id, **kwd ):
+        # This method is used by the select list labeled "Perform action on selected datasets"
+        # on the admin library browser.
+        params = util.Params( kwd )
+        msg = util.restore_text( params.get( 'msg', ''  ) )
+        messagetype = params.get( 'messagetype', 'done' )
+        if params.get( 'action_on_datasets_button', False ):
+            if not params.ldda_ids:
+                msg = "At least one dataset must be selected for %s" % params.action
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action='browse_library',
+                                                           id=library_id,
+                                                           msg=util.sanitize_text( msg ),
+                                                           messagetype='error' ) )
+            ldda_ids = util.listify( params.ldda_ids )
+            if params.action == 'edit':
+                # We need the folder containing the LibraryDatasetDatasetAssociation(s)
+                ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_ids[0] )
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action='library_dataset_dataset_association',
+                                                           library_id=library_id,
+                                                           folder_id=ldda.library_dataset.folder.id,
+                                                           id=",".join( ldda_ids ),
+                                                           permissions=True,
+                                                           msg=util.sanitize_text( msg ),
+                                                           messagetype=messagetype ) )
+            elif params.action == 'delete':
+                for id in ldda_ids:
+                    ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id )
+                    ldda.deleted = True
+                    ldda.flush()
+                msg = "The selected datasets have been removed from this library"
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action='browse_library',
+                                                           id=library_id,
+                                                           show_deleted=False,
+                                                           msg=util.sanitize_text( msg ),
+                                                           messagetype='done' ) )
+            else:
+                msg = "Action %s is not yet implemented" % str( params.action )
+                trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                           action='browse_library',
+                                                           id=library_id,
+                                                           msg=util.sanitize_text( msg ),
+                                                           messagetype='error' ) )
+        else:
+            trans.response.send_redirect( web.url_for( controller='library_admin',
+                                                       action='browse_library',
+                                                           id=library_id,
+                                                       msg=util.sanitize_text( msg ),
+                                                       messagetype=messagetype ) )
+    @web.expose
+    @web.require_admin
+    def delete_library_item( self, trans, library_id, library_item_id, library_item_type ):
+        # This action will handle deleting all types of library items.  State is saved for libraries and
+        # folders ( i.e., if undeleted, the state of contents of the library or folder will remain, so previously
+        # deleted / purged contents will have the same state ).  When a library or folder has been deleted for
+        # the amount of time defined in the cleanup_datasets.py script, the library or folder and all of its
+        # contents will be purged.  The association between this method and the cleanup_datasets.py script
+        # enables clean maintenance of libraries and library dataset disk files.  This is also why the following
+        # 3 objects, and not any of the associations ( the cleanup_datasets.py scipot handles everything else ).
+        library_item_types = { 'library': trans.app.model.Library,
+                               'folder': trans.app.model.LibraryFolder,
+                               'library_dataset': trans.app.model.LibraryDataset }
+        if library_item_type not in library_item_types:
+            msg = 'Bad library_item_type specified: %s' % str( library_item_type )
+            messagetype = 'error'
+        else:
+            if library_item_type == 'library_dataset':
+                library_item_desc = 'Dataset'
+            else:
+                library_item_desc = library_item_type.capitalize()
+            library_item = library_item_types[ library_item_type ].get( int( library_item_id ) )
+            library_item.deleted = True
+            library_item.flush()
+            msg = util.sanitize_text( "%s '%s' has been marked deleted" % ( library_item_desc, library_item.name ) )
+            messagetype = 'done'
+        if library_item_type == 'library':
+            return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
+        else:
+            return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype )
+    @web.expose
+    @web.require_admin
+    def undelete_library_item( self, trans, library_id, library_item_id, library_item_type ):
+        # This action will handle undeleting all types of library items
+        library_item_types = { 'library': trans.app.model.Library,
+                               'folder': trans.app.model.LibraryFolder,
+                               'library_dataset': trans.app.model.LibraryDataset }
+        if library_item_type not in library_item_types:
+            msg = 'Bad library_item_type specified: %s' % str( library_item_type )
+            messagetype = 'error'
+        else:
+            if library_item_type == 'library_dataset':
+                library_item_desc = 'Dataset'
+            else:
+                library_item_desc = library_item_type.capitalize()
+            library_item = library_item_types[ library_item_type ].get( int( library_item_id ) )
+            if library_item.purged:
+                msg = '%s %s has been purged, so it cannot be undeleted' % ( library_item_desc, library_item.name )
+                messagetype = 'error'
+            else:
+                library_item.deleted = False
+                library_item.flush()
+                msg = util.sanitize_text( "%s '%s' has been marked undeleted" % ( library_item_desc, library_item.name ) )
+                messagetype = 'done'
+        if library_item_type == 'library':
+            return self.browse_libraries( trans, msg=msg, messagetype=messagetype )
+        else:
+            return self.browse_library( trans, id=library_id , msg=msg, messagetype=messagetype )
diff -r f2af04af3caa -r d301a67eda40 templates/admin/index.mako
--- a/templates/admin/index.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/index.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -89,7 +89,7 @@
                 </div>
                 <div class="toolSectionBody">
                   <div class="toolSectionBg">
-                    <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_libraries' )}" target="galaxy_main">Manage data libraries</a></div>
+                    <div class="toolTitle"><a href="${h.url_for( controller='library_admin', action='browse_libraries' )}" target="galaxy_main">Manage data libraries</a></div>
                   </div>
                 </div>
                 <div class="toolSectionPad"></div>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/browse_libraries.mako
--- a/templates/admin/library/browse_libraries.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/browse_libraries.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -13,10 +13,10 @@
 <ul class="manage-table-actions">
     %if not deleted:
         <li>
-            <a class="action-button" href="${h.url_for( controller='admin', action='library', new=True )}"><span>Create a new data library</span></a>
+            <a class="action-button" href="${h.url_for( controller='library_admin', action='library', new=True )}"><span>Create a new data library</span></a>
         </li>
         <li>
-            <a class="action-button" href="${h.url_for( controller='admin', action='deleted_libraries' )}"><span>Manage deleted libraries</span></a>
+            <a class="action-button" href="${h.url_for( controller='library_admin', action='deleted_libraries' )}"><span>Manage deleted libraries</span></a>
         </li>
     %endif
 </ul>
@@ -42,7 +42,7 @@
         <tbody>
             %for library in libraries:    
                 <tr class="libraryRow libraryOrFolderRow" id="libraryRow">
-                    <td><a href="${h.url_for( controller='admin', action='browse_library', id=library.id, deleted=deleted, show_deleted=show_deleted )}">${library.name}</a></td>
+                    <td><a href="${h.url_for( controller='library_admin', action='browse_library', id=library.id, deleted=deleted, show_deleted=show_deleted )}">${library.name}</a></td>
                     <td><i>${library.description}</i></td>
                 </tr>             
             %endfor
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/browse_library.mako
--- a/templates/admin/library/browse_library.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/browse_library.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -97,26 +97,26 @@
                             <input type="checkbox" name="ldda_ids" value="${ldda.id}"/>
                         %endif
                         <span class="libraryItemDeleted-${ldda.deleted}">
-                            <a href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, info=True, deleted=deleted, show_deleted=show_deleted )}"><b>${ldda.name[:50]}</b></a>
+                            <a href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, info=True, deleted=deleted, show_deleted=show_deleted )}"><b>${ldda.name[:50]}</b></a>
                         </span>
                         <a id="dataset-${ldda.id}-popup" class="popup-arrow" style="display: none;">▼</a>
                         %if not library.deleted and not folder.deleted and not library_dataset.deleted:
                             <div popupmenu="dataset-${ldda.id}-popup">
-                                <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, edit_info=True )}">Edit this dataset's information</a>
+                                <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, edit_info=True )}">Edit this dataset's information</a>
                                 ## We're disabling the ability to add templates at the LDDA and LibraryDataset level, but will leave this here for possible future use
-                                ##<a class="action-button" href="${h.url_for( controller='admin', action='info_template', library_id=library.id, library_dataset_id=library_dataset.id, new_template=True )}">Add an information template to this dataset</a>
-                                <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, permissions=True )}">Edit this dataset's permissions</a>
+                                ##<a class="action-button" href="${h.url_for( controller='library_admin', action='info_template', library_id=library.id, library_dataset_id=library_dataset.id, new_template=True )}">Add an information template to this dataset</a>
+                                <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, id=ldda.id, permissions=True )}">Edit this dataset's permissions</a>
                                 %if current_version:
-                                    <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, replace_id=library_dataset.id )}">Upload a new version of this dataset</a>
+                                    <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=folder.id, replace_id=library_dataset.id )}">Upload a new version of this dataset</a>
                                 %endif
                                 %if ldda.has_data:
-                                    <a class="action-button" href="${h.url_for( controller='admin', action='download_dataset_from_folder', id=ldda.id, library_id=library.id )}">Download this dataset</a>
+                                    <a class="action-button" href="${h.url_for( controller='library_admin', action='download_dataset_from_folder', id=ldda.id, library_id=library.id )}">Download this dataset</a>
                                 %endif
-                                <a class="action-button" confirm="Click OK to delete dataset '${ldda.name}'." href="${h.url_for( controller='admin', action='delete_library_item', library_id=library.id, library_item_id=library_dataset.id, library_item_type='library_dataset' )}">Delete this dataset</a>
+                                <a class="action-button" confirm="Click OK to delete dataset '${ldda.name}'." href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=library.id, library_item_id=library_dataset.id, library_item_type='library_dataset' )}">Delete this dataset</a>
                             </div>
                         %elif not library.deleted and not folder.deleted and library_dataset.deleted:
                             <div popupmenu="dataset-${ldda.id}-popup">
-                                <a class="action-button" href="${h.url_for( controller='admin', action='undelete_library_item', library_id=library.id, library_item_id=library_dataset.id, library_item_type='library_dataset' )}">Undelete this dataset</a>
+                                <a class="action-button" href="${h.url_for( controller='library_admin', action='undelete_library_item', library_id=library.id, library_item_id=library_dataset.id, library_item_type='library_dataset' )}">Undelete this dataset</a>
                             </div>
                         %endif
                     </td>
@@ -156,23 +156,23 @@
             %endif
             %if not folder.deleted:
                 <div popupmenu="folder-${folder.id}-popup">
-                    <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder.id )}">Add datasets to this folder</a>
-                    <a class="action-button" href="${h.url_for( controller='admin', action='folder', new=True, id=folder.id, library_id=library_id )}">Create a new sub-folder in this folder</a>
-                    <a class="action-button" href="${h.url_for( controller='admin', action='folder', information=True, id=folder.id, library_id=library_id )}">Edit this folder's information</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder.id )}">Add datasets to this folder</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='folder', new=True, id=folder.id, library_id=library_id )}">Create a new sub-folder in this folder</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='folder', information=True, id=folder.id, library_id=library_id )}">Edit this folder's information</a>
                     ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition
                     ##%if folder.info_association:
                     ##    <% form_id = folder.info_association[0].template.id %>
                     ##    <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form_id, show_form=True )}">Edit this folder's information template</a>
                     ##%else:
                     %if not folder.info_association:
-                        <a class="action-button" href="${h.url_for( controller='admin', action='info_template', library_id=library.id, folder_id=folder.id, add=True )}">Add an information template to this folder</a>
+                        <a class="action-button" href="${h.url_for( controller='library_admin', action='info_template', library_id=library.id, folder_id=folder.id, add=True )}">Add an information template to this folder</a>
                     %endif
-                    <a class="action-button" href="${h.url_for( controller='admin', action='folder', permissions=True, id=folder.id, library_id=library_id )}">Edit this folder's permissions</a>
-                    <a class="action-button" confirm="Click OK to delete the folder '${folder.name}.'" href="${h.url_for( controller='admin', action='delete_library_item', library_id=library_id, library_item_id=folder.id, library_item_type='folder' )}">Delete this folder and its contents</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='folder', permissions=True, id=folder.id, library_id=library_id )}">Edit this folder's permissions</a>
+                    <a class="action-button" confirm="Click OK to delete the folder '${folder.name}.'" href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=library_id, library_item_id=folder.id, library_item_type='folder' )}">Delete this folder and its contents</a>
                 </div>
             %elif not deleted and folder.deleted and not folder.purged:
                 <div popupmenu="folder-${folder.id}-popup">
-                    <a class="action-button" href="${h.url_for( controller='admin', action='undelete_library_item', library_id=library_id, library_item_id=folder.id, library_item_type='folder' )}">Undelete this folder</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='undelete_library_item', library_id=library_id, library_item_id=folder.id, library_item_type='folder' )}">Undelete this folder</a>
                 </div>
             %endif
         </li>
@@ -216,10 +216,10 @@
 <ul class="manage-table-actions">
     %if not deleted:
         <li>
-            <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=library.root_folder.id )}"><span>Add datasets to this data library</span></a>
+            <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library.id, folder_id=library.root_folder.id )}"><span>Add datasets to this data library</span></a>
         </li>
         <li>
-            <a class="action-button" href="${h.url_for( controller='admin', action='folder', new=True, id=library.root_folder.id, library_id=library.id )}">Add a folder to this data library</a>
+            <a class="action-button" href="${h.url_for( controller='library_admin', action='folder', new=True, id=library.root_folder.id, library_id=library.id )}">Add a folder to this data library</a>
         </li>
     %endif
 </ul>
@@ -228,7 +228,7 @@
     ${render_msg( msg, messagetype )}
 %endif
 
-<form name="update_multiple_datasets" action="${h.url_for( controller='admin', action='datasets', library_id=library.id )}" onSubmit="javascript:return checkForm();" method="post">
+<form name="update_multiple_datasets" action="${h.url_for( controller='library_admin', action='datasets', library_id=library.id )}" onSubmit="javascript:return checkForm();" method="post">
     <ul>
         <li class="libraryRow libraryOrFolderRow" id="libraryRow">
             <div class="rowTitle">
@@ -244,24 +244,24 @@
                         <a id="library-${library.id}-popup" class="popup-arrow" style="display: none;">▼</a>
                         <div popupmenu="library-${library.id}-popup">
                         %if not deleted:
-                            <a class="action-button" href="${h.url_for( controller='admin', action='library', id=library.id, information=True )}">Edit this data library's information</a>
+                            <a class="action-button" href="${h.url_for( controller='library_admin', action='library', id=library.id, information=True )}">Edit this data library's information</a>
                             ## Editing templates disabled until we determine optimal approach to re-linking library item to new version of form definition
                             ##%if library.info_association:
                             ##    <% form_id = library.info_association[0].template.id %>
                             ##    <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form_id, show_form=True )}">Edit this data library's information template</a>
                             ##%else:
                             %if not library.info_association:
-                                <a class="action-button" href="${h.url_for( controller='admin', action='info_template', library_id=library.id, add=True )}">Add an information template to this data library</a>
+                                <a class="action-button" href="${h.url_for( controller='library_admin', action='info_template', library_id=library.id, add=True )}">Add an information template to this data library</a>
                             %endif
-                            <a class="action-button" href="${h.url_for( controller='admin', action='library', id=library.id, permissions=True )}">Edit this data library's permissions</a>
-                            <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='admin', action='delete_library_item', library_id=library.id, library_item_id=library.id, library_item_type='library' )}">Delete this data library and its contents</a>
+                            <a class="action-button" href="${h.url_for( controller='library_admin', action='library', id=library.id, permissions=True )}">Edit this data library's permissions</a>
+                            <a class="action-button" confirm="Click OK to delete the library named '${library.name}'." href="${h.url_for( controller='library_admin', action='delete_library_item', library_id=library.id, library_item_id=library.id, library_item_type='library' )}">Delete this data library and its contents</a>
                             %if show_deleted:
-                            	<a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library.id, show_deleted=False )}">Hide deleted data library items</a>
+                            	<a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library.id, show_deleted=False )}">Hide deleted data library items</a>
                             %else:
-                            	<a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library.id, show_deleted=True )}">Show deleted data library items</a>
+                            	<a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library.id, show_deleted=True )}">Show deleted data library items</a>
                             %endif
                         %elif not library.purged:
-                              <a class="action-button" href="${h.url_for( controller='admin', action='undelete_library_item', library_id=library.id, library_item_id=library.id, library_item_type='library' )}">Undelete this data library</a>
+                              <a class="action-button" href="${h.url_for( controller='library_admin', action='undelete_library_item', library_id=library.id, library_item_id=library.id, library_item_type='library' )}">Undelete this data library</a>
                         %endif
                         </div>
                     </th>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/common.mako
--- a/templates/admin/library/common.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/common.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -22,7 +22,7 @@
             <div class="toolFormTitle">Other information about ${library_item_desc} ${library_item.name}</div>
             <div class="toolFormBody">
                 %if editable:
-                    <form name="edit_info" action="${h.url_for( controller='admin', action='edit_template_info', library_id=library_id, num_widgets=len( widgets ) )}" method="post">
+                    <form name="edit_info" action="${h.url_for( controller='library_admin', action='edit_template_info', library_id=library_id, num_widgets=len( widgets ) )}" method="post">
                         <input type="hidden" name="library_item_id" value="${library_item.id}"/>
                         <input type="hidden" name="library_item_type" value="${library_item_type}"/>
                         %for i, field in enumerate( widgets ):
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/folder_info.mako
--- a/templates/admin/library/folder_info.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/folder_info.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -5,7 +5,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -16,7 +16,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Edit folder name and description</div>
     <div class="toolFormBody">
-        <form name="folder" action="${h.url_for( controller='admin', action='folder', information=True, id=folder.id, library_id=library_id )}" method="post" >
+        <form name="folder" action="${h.url_for( controller='library_admin', action='folder', information=True, id=folder.id, library_id=library_id )}" method="post" >
             <div class="form-row">
                 <label>Name:</label>
                 <input type="text" name="name" value="${folder.name}" size="40"/>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/folder_permissions.mako
--- a/templates/admin/library/folder_permissions.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/folder_permissions.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -5,7 +5,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -17,4 +17,4 @@
     roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all()
 %>
 
-${render_permission_form( folder, folder.name, h.url_for( controller='admin', action='folder', id=folder.id, library_id=library_id, permissions=True ), roles )}
+${render_permission_form( folder, folder.name, h.url_for( controller='library_admin', action='folder', id=folder.id, library_id=library_id, permissions=True ), roles )}
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/ldda_edit_info.mako
--- a/templates/admin/library/ldda_edit_info.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/ldda_edit_info.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -12,7 +12,7 @@
 
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -35,7 +35,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Edit attributes of ${ldda.name}</div>
     <div class="toolFormBody">
-        <form name="edit_attributes" action="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
+        <form name="edit_attributes" action="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
             <input type="hidden" name="id" value="${ldda.id}"/>
             <br/>
             <div class="form-row">
@@ -73,7 +73,7 @@
                 <input type="submit" name="save" value="Save"/>
             </div>
         </form>
-        <form name="auto_detect" action="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
+        <form name="auto_detect" action="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
             <div class="form-row">
                 <input type="hidden" name="id" value="${ldda.id}"/>
                 <input type="submit" name="detect" value="Auto-detect"/>
@@ -89,7 +89,7 @@
     <div class="toolFormTitle">Change data type of ${ldda.name}</div>
     <div class="toolFormBody">
         %if ldda.datatype.allow_datatype_change:
-            <form name="change_datatype" action="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
+            <form name="change_datatype" action="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, edit_info=True )}" method="post">
                 <input type="hidden" name="id" value="${ldda.id}"/>
                 <div class="form-row">
                     <label>New Type:</label>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/ldda_info.mako
--- a/templates/admin/library/ldda_info.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/ldda_info.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -20,7 +20,7 @@
 
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id, deleted=library.deleted, show_deleted=show_deleted )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id, deleted=library.deleted, show_deleted=show_deleted )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -41,18 +41,18 @@
         %if not library.deleted and not ldda.library_dataset.folder.deleted and not ldda.deleted:
             <a id="dataset-${ldda.id}-popup" class="popup-arrow" style="display: none;">▼</a>
             <div popupmenu="dataset-${ldda.id}-popup">
-                <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, edit_info=True )}">Edit this dataset's information</a>
+                <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, edit_info=True )}">Edit this dataset's information</a>
                 ## We're disabling the ability to add templates at the LDDA and LibraryDataset level, but will leave this here for possible future use
-                ##<a class="action-button" href="${h.url_for( controller='admin', action='info_template', library_id=library_id, library_dataset_id=ldda.library_dataset.id, new_template=True )}">Add an information template to this dataset</a>
-                <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, permissions=True )}">Edit this dataset's permissions</a>
+                ##<a class="action-button" href="${h.url_for( controller='library_admin', action='info_template', library_id=library_id, library_dataset_id=ldda.library_dataset.id, new_template=True )}">Add an information template to this dataset</a>
+                <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, permissions=True )}">Edit this dataset's permissions</a>
                 %if current_version:
-                    <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, replace_id=ldda.library_dataset.id )}">Upload a new version of this dataset</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, replace_id=ldda.library_dataset.id )}">Upload a new version of this dataset</a>
                 %endif
                 %if ldda.has_data:
-                    <a class="action-button" href="${h.url_for( controller='admin', action='download_dataset_from_folder', id=ldda.id, library_id=library_id )}">Download this dataset</a>
+                    <a class="action-button" href="${h.url_for( controller='library_admin', action='download_dataset_from_folder', id=ldda.id, library_id=library_id )}">Download this dataset</a>
                 %endif
                 %if not library.deleted and not ldda.library_dataset.folder.deleted and not ldda.deleted:
-                    <a class="action-button" confirm="Click OK to remove dataset '${ldda.name}'?" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, delete=True )}">Delete this dataset</a>
+                    <a class="action-button" confirm="Click OK to remove dataset '${ldda.name}'?" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=ldda.library_dataset.folder.id, id=ldda.id, delete=True )}">Delete this dataset</a>
                 %endif
             </div>
         %endif
@@ -104,7 +104,7 @@
             <div class="toolFormTitle">Expired versions of ${ldda.name}</div>
             %for expired_ldda in expired_lddas:
                 <div class="form-row">
-                    <a href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=expired_ldda.library_dataset.folder.id, id=expired_ldda.id, info=True )}">${expired_ldda.name}</a>
+                    <a href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=expired_ldda.library_dataset.folder.id, id=expired_ldda.id, info=True )}">${expired_ldda.name}</a>
                 </div>
             %endfor
         %endif
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/ldda_permissions.mako
--- a/templates/admin/library/ldda_permissions.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/ldda_permissions.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -15,7 +15,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -35,7 +35,7 @@
                         <a id="ldda-${ldd_assoc.id}-popup" class="popup-arrow" style="display: none;">▼</a>
                     </div>
                     <div popupmenu="ldd_assoc-${ldd_assoc.id}-popup">
-                        <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset', id=ldd_assoc.library_dataset_id, library_id=library_id )}">Manage this dataset's versions</a>
+                        <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset', id=ldd_assoc.library_dataset_id, library_id=library_id )}">Manage this dataset's versions</a>
                     </div>
                 </td>
                 <td>
@@ -59,4 +59,4 @@
 %endif
 
 <% ldda_ids = ",".join( [ str( d.id ) for d in lddas ] ) %>
-${render_permission_form( lddas[0], name_str, h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, id=ldda_ids, permissions=True ), roles )}
+${render_permission_form( lddas[0], name_str, h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=lddas[0].library_dataset.folder.id, id=ldda_ids, permissions=True ), roles )}
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/library_dataset_info.mako
--- a/templates/admin/library/library_dataset_info.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/library_dataset_info.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -11,7 +11,7 @@
 
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -22,7 +22,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Edit attributes of ${library_dataset.name}</div>
     <div class="toolFormBody">
-        <form name="edit_attributes" action="${h.url_for( controller='admin', action='library_dataset' )}" method="post">
+        <form name="edit_attributes" action="${h.url_for( controller='library_admin', action='library_dataset' )}" method="post">
             <input type="hidden" name="id" value="${library_dataset.id}"/>
             <div class="form-row">
                 <label>Name:</label>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/library_dataset_permissions.mako
--- a/templates/admin/library/library_dataset_permissions.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/library_dataset_permissions.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -11,7 +11,7 @@
 
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -23,4 +23,4 @@
     roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.table.c.name ).all()
 %>
 
-${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='admin', action='library_dataset', id=library_dataset.id, library_id=library_id, permissions=True ), roles )}
+${render_permission_form( library_dataset, library_dataset.name, h.url_for( controller='library_admin', action='library_dataset', id=library_dataset.id, library_id=library_id, permissions=True ), roles )}
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/library_info.mako
--- a/templates/admin/library/library_info.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/library_info.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -5,7 +5,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library.id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library.id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -16,7 +16,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Change library name and description</div>
     <div class="toolFormBody">
-        <form name="library" action="${h.url_for( controller='admin', action='library', information=True, id=library.id )}" method="post" >
+        <form name="library" action="${h.url_for( controller='library_admin', action='library', information=True, id=library.id )}" method="post" >
             <div class="form-row">
                 <label>Name:</label>
                 <div style="float: left; width: 250px; margin-right: 10px;">
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/library_permissions.mako
--- a/templates/admin/library/library_permissions.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/library_permissions.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -5,7 +5,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library.id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library.id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/new_dataset.mako
--- a/templates/admin/library/new_dataset.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/new_dataset.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -7,16 +7,16 @@
 <b>Create new data library datasets</b>
 <a id="upload-librarydataset--popup" class="popup-arrow" style="display: none;">▼</a>
 <div popupmenu="upload-librarydataset--popup">
-    <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='upload_file' )}">Upload files</a>
+    <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='upload_file' )}">Upload files</a>
     %if trans.app.config.library_import_dir and os.path.exists( trans.app.config.library_import_dir ):
-        <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='upload_directory' )}">Upload directory of files</a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='upload_directory' )}">Upload directory of files</a>
     %endif
-    <a class="action-button" href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='import_from_history' )}">Import datasets from your current history</a>
+    <a class="action-button" href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, replace_id=replace_id, upload_option='import_from_history' )}">Import datasets from your current history</a>
 </div>
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -32,13 +32,13 @@
             <div class="toolFormTitle">Upload a directory of files</div>
         %endif
         <div class="toolFormBody">
-            <form name="tool_form" action="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id )}" enctype="multipart/form-data" method="post">
+            <form name="tool_form" action="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id )}" enctype="multipart/form-data" method="post">
                 <input type="hidden" name="folder_id" value="${folder_id}"/>
                 <input type="hidden" name="upload_option" value="${upload_option}"/>
                 %if replace_dataset:
                     <input type="hidden" name="replace_id" value="${replace_dataset.id}"/>
                     <div class="form-row">
-                        You are currently selecting a new file to replace '<a href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, id=replace_dataset.library_dataset_dataset_association.id )}">${replace_dataset.name}</a>'.
+                        You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, id=replace_dataset.library_dataset_dataset_association.id )}">${replace_dataset.name}</a>'.
                         <div style="clear: both"></div>
                     </div>
                 %endif
@@ -184,13 +184,13 @@
         <div class="toolFormTitle">Active datasets in your current history (${history.name})</div>
         <div class="toolFormBody">
             %if history and history.active_datasets:
-                <form name="add_history_datasets_to_library" action="${h.url_for( controller='admin', action='add_history_datasets_to_library', library_id=library_id )}" enctype="multipart/form-data" method="post">
+                <form name="add_history_datasets_to_library" action="${h.url_for( controller='library_admin', action='add_history_datasets_to_library', library_id=library_id )}" enctype="multipart/form-data" method="post">
                     <input type="hidden" name="folder_id" value="${folder_id}"/>
                     <input type="hidden" name="upload_option" value="${upload_option}"/>
                     %if replace_dataset:
                         <input type="hidden" name="replace_id" value="${replace_dataset.id}"/>
                         <div class="form-row">
-                            You are currently selecting a new file to replace '<a href="${h.url_for( controller='admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, id=replace_dataset.library_dataset_dataset_association.id )}">${replace_dataset.name}</a>'.
+                            You are currently selecting a new file to replace '<a href="${h.url_for( controller='library_admin', action='library_dataset_dataset_association', library_id=library_id, folder_id=folder_id, id=replace_dataset.library_dataset_dataset_association.id )}">${replace_dataset.name}</a>'.
                             <div style="clear: both"></div>
                         </div>
                     %endif
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/new_folder.mako
--- a/templates/admin/library/new_folder.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/new_folder.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -4,7 +4,7 @@
 <br/<br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -15,7 +15,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Create a new folder</div>
     <div class="toolFormBody">
-        <form name="folder" action="${h.url_for( controller='admin', action='folder', id=folder.id, library_id=library_id )}" method="post" >
+        <form name="folder" action="${h.url_for( controller='library_admin', action='folder', id=folder.id, library_id=library_id )}" method="post" >
             <div class="form-row">
                 <label>Name:</label>
                 <div style="float: left; width: 250px; margin-right: 10px;">
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/new_library.mako
--- a/templates/admin/library/new_library.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/new_library.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -8,7 +8,7 @@
 <div class="toolForm">
     <div class="toolFormTitle">Create a new data library</div>
     <div class="toolFormBody">
-        <form name="library" action="${h.url_for( controller='admin', action='library' )}" method="post" >
+        <form name="library" action="${h.url_for( controller='library_admin', action='library' )}" method="post" >
             <div class="form-row">
                 <label>Name:</label>
                 <div style="float: left; width: 250px; margin-right: 10px;">
diff -r f2af04af3caa -r d301a67eda40 templates/admin/library/select_info_template.mako
--- a/templates/admin/library/select_info_template.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/library/select_info_template.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -4,7 +4,7 @@
 <br/><br/>
 <ul class="manage-table-actions">
     <li>
-        <a class="action-button" href="${h.url_for( controller='admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
+        <a class="action-button" href="${h.url_for( controller='library_admin', action='browse_library', id=library_id )}"><span>Browse this data library</span></a>
     </li>
 </ul>
 
@@ -14,7 +14,7 @@
 
 <div class="toolForm">
     <div class="toolFormTitle">Select a form on which to base the template for the ${library_item_desc} '${library_item_name}'</div>
-    <form name="new_info_template" action="${h.url_for( controller='admin', action='info_template', add=True )}" method="post" >
+    <form name="new_info_template" action="${h.url_for( controller='library_admin', action='info_template', add=True )}" method="post" >
         <div class="toolFormBody">
             <div class="form-row">
                 <input type="hidden" name="library_id" value="${library_id}"/>
diff -r f2af04af3caa -r d301a67eda40 templates/admin/requests/show_request.mako
--- a/templates/admin/requests/show_request.mako	Fri Sep 11 16:09:02 2009 -0400
+++ b/templates/admin/requests/show_request.mako	Mon Sep 14 11:05:36 2009 -0400
@@ -80,7 +80,7 @@
                         <i>None</i>
                     %else:                      
                         %if rd['label'] == 'Data library':
-                            <a href="${h.url_for( controller='admin', action='browse_library', id=request.library.id )}">${rd['value']}</a>
+                            <a href="${h.url_for( controller='library_admin', action='browse_library', id=request.library.id )}">${rd['value']}</a>
                         %else:
                             ${rd['value']}     
                         %endif
diff -r f2af04af3caa -r d301a67eda40 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py	Fri Sep 11 16:09:02 2009 -0400
+++ b/test/base/twilltestcase.py	Mon Sep 14 11:05:36 2009 -0400
@@ -1139,14 +1139,14 @@
     def create_library( self, name='Library One', description='This is Library One' ):
         """Create a new library"""
         self.home()
-        self.visit_url( "%s/admin/library?new=True" % self.url )
+        self.visit_url( "%s/library_admin/library?new=True" % self.url )
         self.check_page_for_string( 'Create a new data library' )
         tc.fv( "1", "1", name ) # form field 1 is the field named name...
         tc.fv( "1", "2", description ) # form field 1 is the field named name...
         tc.submit( "create_library_button" )
         self.home()
     def set_library_permissions( self, library_id, library_name, role_id, permissions_in, permissions_out ):
-        url = "admin/library?id=%s&permissions=True&update_roles_button=Save" % ( library_id )
+        url = "library_admin/library?id=%s&permissions=True&update_roles_button=Save" % ( library_id )
         for po in permissions_out:
             key = '%s_out' % po
             url ="%s&%s=%s" % ( url, key, str( role_id ) )
@@ -1161,10 +1161,10 @@
     def rename_library( self, library_id, old_name, name='Library One Renamed', description='This is Library One Re-described' ):
         """Rename a library"""
         self.home()
-        self.visit_url( "%s/admin/library?information=True&id=%s" % ( self.url, library_id ) )
+        self.visit_url( "%s/library_admin/library?information=True&id=%s" % ( self.url, library_id ) )
         self.check_page_for_string( 'Change library name and description' )
         # Since twill barfs on the form submisson, we ar forced to simulate it
-        url = "%s/admin/library?information=True&id=%s&rename_library_button=Save&description=%s&name=%s" % \
+        url = "%s/library_admin/library?information=True&id=%s&rename_library_button=Save&description=%s&name=%s" % \
         ( self.url, library_id, description.replace( ' ', '+' ), name.replace( ' ', '+' ) )
         self.home()
         self.visit_url( url )
@@ -1174,7 +1174,7 @@
     def add_library_info_template( self, library_id, library_name, form_id, form_name ):
         """Add a new info template to a library"""
         self.home()
-        url = "%s/admin/info_template?library_id=%s&add=True" % ( self.url, library_id )
+        url = "%s/library_admin/info_template?library_id=%s&add=True" % ( self.url, library_id )
         self.visit_url( url )
         self.check_page_for_string ( "Select a form on which to base the template" )
         tc.fv( '1', 'library_id', library_id )
@@ -1184,7 +1184,7 @@
     def edit_library_info( self, library_id, library_name, ele_1_field_name, ele_1_contents, ele_2_field_name, ele_2_contents ):
         """Add information to a library using an existing template with 2 elements"""
         self.home()
-        self.visit_url( "%s/admin/library?information=True&id=%s" % ( self.url, library_id ) )
+        self.visit_url( "%s/library_admin/library?information=True&id=%s" % ( self.url, library_id ) )
         check_str = 'Other information about library %s' % library_name
         self.check_page_for_string( check_str )
         tc.fv( '2', ele_1_field_name, ele_1_contents )
@@ -1195,7 +1195,7 @@
                                     ele_desc_1, desc_1, ele_name_2, name_2, ele_desc_2, desc_2 ):
         """Edit an existing library info template"""
         self.home()
-        url = "%s/admin/info_template?library_id=%s&id=%s&edit_template=True" % ( self.url, library_id, id )
+        url = "%s/library_admin/info_template?library_id=%s&id=%s&edit_template=True" % ( self.url, library_id, id )
         self.visit_url( url )
         self.check_page_for_string ( 'Edit template' )
         tc.fv( '1', 'id', id )
@@ -1213,7 +1213,7 @@
                                   name='Folder Template 1', ele_name_0='Fu', ele_help_0='', ele_name_1='Bar', ele_help_1='' ):
         """Add a new info template to a folder"""
         self.home()
-        url = "%s/admin/info_template?library_id=%s&folder_id=%s&new_template=True&num_fields=2&create_info_template_button=Go" % \
+        url = "%s/library_admin/info_template?library_id=%s&folder_id=%s&new_template=True&num_fields=2&create_info_template_button=Go" % \
             ( self.url, library_id, folder_id )
         self.home()
         self.visit_url( url )
@@ -1232,7 +1232,7 @@
     def add_folder( self, library_id, folder_id, name='Folder One', description='This is Folder One' ):
         """Create a new folder"""
         self.home()
-        self.visit_url( "%s/admin/folder?library_id=%s&id=%s&new=True" % ( self.url, library_id, folder_id ) )
+        self.visit_url( "%s/library_admin/folder?library_id=%s&id=%s&new=True" % ( self.url, library_id, folder_id ) )
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/355b6844b123
changeset: 2684:355b6844b123
user:      jeremy goecks <jeremy.goecks(a)emory.edu>
date:      Fri Sep 11 15:04:53 2009 -0400
description:
Merge
0 file(s) affected in this change:
diffs (878 lines):
diff -r 032478337b82 -r 355b6844b123 eggs.ini
--- a/eggs.ini	Fri Sep 11 14:57:02 2009 -0400
+++ b/eggs.ini	Fri Sep 11 15:04:53 2009 -0400
@@ -31,7 +31,7 @@
 elementtree = 1.2.6_20050316
 lrucache = 0.2
 ;lsprof - james
-Mako = 0.2.4
+Mako = 0.2.5
 MyghtyUtils = 0.52
 nose = 0.9.1
 NoseHTML = 0.2
@@ -79,7 +79,7 @@
 docutils = http://downloads.sourceforge.net/docutils/docutils-0.4.tar.gz
 elementtree = http://effbot.org/downloads/elementtree-1.2.6-20050316.tar.gz
 lrucache = http://evan.prodromou.name/lrucache/lrucache-0.2.tar.gz
-Mako = http://www.makotemplates.org/downloads/Mako-0.2.4.tar.gz
+Mako = http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz
 MyghtyUtils = http://cheeseshop.python.org/packages/source/M/MyghtyUtils/MyghtyUtils-0.52…
 nose = http://www.somethingaboutorange.com/mrl/projects/nose/nose-0.9.1.tar.gz
 NoseHTML = http://dist.g2.bx.psu.edu/nosehtml-0.2.tar.bz2
diff -r 032478337b82 -r 355b6844b123 scripts/cleanup_datasets/cleanup_datasets.py
--- a/scripts/cleanup_datasets/cleanup_datasets.py	Fri Sep 11 14:57:02 2009 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py	Fri Sep 11 15:04:53 2009 -0400
@@ -1,4 +1,8 @@
 #!/usr/bin/env python
+
+from galaxy import eggs
+import pkg_resources  
+pkg_resources.require( "SQLAlchemy >= 0.4" )
 
 import sys, os, time, ConfigParser, shutil
 from datetime import datetime, timedelta
@@ -9,12 +13,7 @@
 new_path.extend( sys.path[1:] ) # remove scripts/ from the path
 sys.path = new_path
 
-from galaxy import eggs
 import galaxy.model.mapping
-import pkg_resources
-        
-pkg_resources.require( "SQLAlchemy >= 0.4" )
-
 from galaxy.model.orm import and_, eagerload
 
 assert sys.version_info[:2] >= ( 2, 4 )
diff -r 032478337b82 -r 355b6844b123 templates/workflow/run.mako
--- a/templates/workflow/run.mako	Fri Sep 11 14:57:02 2009 -0400
+++ b/templates/workflow/run.mako	Fri Sep 11 15:04:53 2009 -0400
@@ -87,8 +87,7 @@
                     ${param.get_html_field( t, value, other_values ).get_html( str(step.id) + "|" + prefix )}
                     <input type="hidden" name="${step.id}|__force_update__${prefix}${param.name}" value="true" />
                 %endif
-            %elif isinstance( value, RuntimeValue ) or \
-                  ( str(step.id) + '|__runtime__' + prefix + param.name ) in incoming:
+            %elif isinstance( value, RuntimeValue ) or ( str(step.id) + '|__runtime__' + prefix + param.name ) in incoming:
                 ## On the first load we may see a RuntimeValue, so we write
                 ## an input field using the initial value for the param.
                 ## Subsequents posts will no longer have the runtime value
diff -r 032478337b82 -r 355b6844b123 test-data/bowtie_in1.fastq
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/bowtie_in1.fastq	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,5 @@
+@HWI-EAS91_1_30788AAXX:1:1:1513:715/1
+GTTTTTTNNGCATAGATGTTTAGTTGTGGTAGTCAG
++/1
+IIIIIII""IIIIIIIIIIIIIIIIIIIDI?II-+I
+
diff -r 032478337b82 -r 355b6844b123 test-data/bowtie_in2.fastq
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/bowtie_in2.fastq	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,4 @@
+@HWI-EAS91_1_30788AAXX:1:2:618:346/1
+TAGACTACGAAAGTGACTTTAATACCTCTGACTACA
++
+IIIIIIIIIIIIIIIIIIIIIIIIIIIII%4II;I3
diff -r 032478337b82 -r 355b6844b123 test-data/bowtie_in3.fastq
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/bowtie_in3.fastq	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,4 @@
+@HWI-EAS91_1_30788AAXX:1:2:618:346/2
+ATAGGCTGAATTAGCAATGGATGGTGGGGTTTATCG
++
+IIIIIIIIIIIIIII9I.II5II6DFIIIIII*I2)
diff -r 032478337b82 -r 355b6844b123 test-data/bowtie_out1.sam
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/bowtie_out1.sam	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,1 @@
+HWI-EAS91_1_30788AAXX:1:1:1513:715	16	chrM	9563	25	36M	*	0	0	CTGACTACCACAACTAAACATCTATGCNNAAAAAAC	I+-II?IDIIIIIIIIIIIIIIIIIII""IIIIIII	NM:i:1	X1:i:1	MD:Z:7N0N27
diff -r 032478337b82 -r 355b6844b123 test-data/bowtie_out2.sam
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/bowtie_out2.sam	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,2 @@
+HWI-EAS91_1_30788AAXX:1:2:618:346	0	chrM	441	25	36M	*	0	0	TAGACTACGAAAGTGACTTTAATACCTCTGACTACA	IIIIIIIIIIIIIIIIIIIIIIIIIIIII%4II;I3	NM:i:0	X0:i:1	MD:Z:36
+HWI-EAS91_1_30788AAXX:1:2:618:346	16	chrM	652	25	36M	*	0	0	CGATAAACCCCACCATCCATTGCTAATTCAGCCTAT	)2I*IIIIIIFD6II5II.I9IIIIIIIIIIIIIII	NM:i:1	X1:i:1	MD:Z:17A18
diff -r 032478337b82 -r 355b6844b123 tool-data/bowtie_indices.loc.sample
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tool-data/bowtie_indices.loc.sample	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,28 @@
+#This is a sample file distributed with Galaxy that enables tools
+#to use a directory of Bowtie indexed sequences data files.  You will need
+#to create these data files and then create a bowtie_indices.loc file 
+#similar to this one (store it in this directory ) that points to 
+#the directories in which those files are stored.  The bowtie_indices.loc 
+#file has this format (white space characters are TAB characters):
+#
+#<build>	<file_base>
+#
+#So, for example, if you had hg18 indexed stored in 
+#/depot/data2/galaxy/bowtie/hg18/, 
+#then the bowtie_indices.loc entry would look like this:
+#
+#hg18	/depot/data2/galaxy/bowtie/hg18/hg18
+#
+#and your /depot/data2/galaxy/bowtie/hg18/ directory
+#would contain hg18.*.ebwt files:
+#
+#-rw-r--r--  1 james    universe 830134 2005-09-13 10:12 hg18.1.ebwt
+#-rw-r--r--  1 james    universe 527388 2005-09-13 10:12 hg18.2.ebwt
+#-rw-r--r--  1 james    universe 269808 2005-09-13 10:12 gh18.3.ebwt
+#...etc...
+#
+#Your bowtie_indices.loc file should include an entry per line for 
+#each index set you have stored.  The "file" in the path does not actually
+#exist, but it is the prefix for the actual index files.  For example:
+#
+#hg18	/depot/data2/galaxy/bowtie/hg18/hg18
diff -r 032478337b82 -r 355b6844b123 tool_conf.xml.sample
--- a/tool_conf.xml.sample	Fri Sep 11 14:57:02 2009 -0400
+++ b/tool_conf.xml.sample	Fri Sep 11 15:04:53 2009 -0400
@@ -332,7 +332,8 @@
    <tool file="metag_tools/megablast_xml_parser.xml" />
    <tool file="metag_tools/blat_wrapper.xml" />
    <tool file="metag_tools/mapping_to_ucsc.xml" />
-   </section>
+   <tool file="sr_mapping/bowtie_wrapper.xml" />
+  </section>
   <section name="Tracks" id="tracks">
    <tool file="visualization/genetrack.xml" />
   </section>
diff -r 032478337b82 -r 355b6844b123 tools/sr_mapping/bowtie_wrapper.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/sr_mapping/bowtie_wrapper.py	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,174 @@
+#! /usr/bin/python
+
+"""
+Runs Bowtie on single-end or paired-end data.
+"""
+
+import optparse, os, sys, tempfile
+
+def stop_err( msg ):
+    sys.stderr.write( "%s\n" % msg )
+    sys.exit()
+ 
+def __main__():
+    #Parse Command Line
+    parser = optparse.OptionParser()
+    parser.add_option('', '--input1', dest='input1', help='The (forward or single-end) reads file in Sanger FASTQ format')
+    parser.add_option('', '--input2', dest='input2', help='The reverse reads file in Sanger FASTQ format')
+    parser.add_option('', '--output', dest='output', help='The output file')
+    parser.add_option('', '--paired', dest='paired', help='Whether the data is single- or paired-end')
+    parser.add_option('', '--genomeSource', dest='genomeSource', help='The type of reference provided')
+    parser.add_option('', '--ref', dest='ref', help='The reference genome to use or index')
+    parser.add_option('', '--skip', dest='skip', help='Skip the first n reads')
+    parser.add_option('', '--alignLimit', dest='alignLimit', help='Only align the first n reads')
+    parser.add_option('', '--trimH', dest='trimH', help='Trim n bases from high-quality (left) end of each read before alignment')
+    parser.add_option('', '--trimL', dest='trimL', help='Trim n bases from low-quality (right) end of each read before alignment')
+    parser.add_option('', '--mismatchSeed', dest='mismatchSeed', help='Maximum number of mismatches permitted in the seed')
+    parser.add_option('', '--mismatchQual', dest='mismatchQual', help='Maximum permitted total of quality values at mismatched read positions')
+    parser.add_option('', '--seedLen', dest='seedLen', help='Seed length')
+    parser.add_option('', '--rounding', dest='rounding', help='Whether or not to round to the nearest 10 and saturating at 30')
+    parser.add_option('', '--maqSoapAlign', dest='maqSoapAlign', help='Choose MAQ- or SOAP-like alignment policy')
+    parser.add_option('', '--tryHard', dest='tryHard', help='Whether or not to try as hard as possible to find valid alignments when they exist')
+    parser.add_option('', '--valAlign', dest='valAlign', help='Report up to n valid arguments per read')
+    parser.add_option('', '--allValAligns', dest='allValAligns', help='Whether or not to report all valid alignments per read')
+    parser.add_option('', '--suppressAlign', dest='suppressAlign', help='Suppress all alignments for a read if more than n reportable alignments exist')
+    parser.add_option('', '--offbase', dest='offbase', help='Number the first base of a reference sequence as n when outputting alignments')
+    parser.add_option('', '--best', dest='best', help="Whether or not to make Bowtie guarantee that reported singleton alignments are 'best' in terms of stratum and in terms of the quality values at the mismatched positions")
+    parser.add_option('', '--maxBacktracks', dest='maxBacktracks', help='Maximum number of backtracks permitted when aligning a read')
+    parser.add_option('', '--threadMem', dest='threadMem', help='Number of megabytes of memory a given thread is given to store path descriptors in best mode')
+    parser.add_option('', '--strata', dest='strata', help='Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable')
+    parser.add_option('', '--minInsert', dest='minInsert', help='Minimum insert size for valid paired-end alignments')
+    parser.add_option('', '--maxInsert', dest='maxInsert', help='Maximum insert size for valid paired-end alignments')
+    parser.add_option('', '--mateOrient', dest='mateOrient', help='The upstream/downstream mate orientation for valid paired-end alignment against the forward reference strand')
+    parser.add_option('', '--maxAlignAttempt', dest='maxAlignAttempt', help='Maximum number of attempts Bowtie will make to match an alignment for one mate with an alignment for the opposite mate')
+    parser.add_option('', '--forwardAlign', dest='forwardAlign', help='Whether or not to attempt to align the forward reference strand')
+    parser.add_option('', '--reverseAlign', dest='reverseAlign', help='Whether or not to attempt to align the reverse-complement reference strand')
+    parser.add_option('', '--phased', dest='phased', help='Whether or not it should alternate between using the forward and mirror indexes in a series of phases so that only half of the index is resident in memory at one time')
+    parser.add_option('', '--offrate', dest='offrate', help='Override the offrate of the index to n')
+    parser.add_option('', '--mm', dest='mm', help='Whether or not to use memory-mapped I/O to load the index')
+    parser.add_option('', '--seed', dest='seed', help='Seed for pseudo-random number generator')
+    parser.add_option('', '--dbkey', dest='dbkey', help='')
+    parser.add_option('', '--params', dest='params', help='Whether to use default or specified parameters')
+    parser.add_option('', '--iauto_b', dest='iauto_b', help='Automatic or specified behavior')
+    parser.add_option('', '--ipacked', dest='ipacked', help='Whether or not to use a packed representation for DNA strings')
+    parser.add_option('', '--ibmax', dest='ibmax', help='Maximum number of suffixes allowed in a block')
+    parser.add_option('', '--ibmaxdivn', dest='ibmaxdivn', help='Maximum number of suffixes allowed in a block as a fraction of the length of the reference')
+    parser.add_option('', '--idcv', dest='idcv', help='The period for the difference-cover sample')
+    parser.add_option('', '--inodc', dest='inodc', help='Whether or not to disable the use of the difference-cover sample')
+    parser.add_option('', '--inoref', dest='inoref', help='Whether or not to build the part of the reference index used only in paried-end alignment')
+    parser.add_option('', '--ioffrate', dest='ioffrate', help='How many rows get marked during annotation of some or all of the Burrows-Wheeler rows')
+    parser.add_option('', '--iftab', dest='iftab', help='The size of the lookup table used to calculate an initial Burrows-Wheeler range with respect to the first n characters of the query')
+    parser.add_option('', '--intoa', dest='intoa', help='Whether or not to convert Ns in the reference sequence to As')
+    parser.add_option('', '--iendian', dest='iendian', help='Endianness to use when serializing integers to the index file')
+    parser.add_option('', '--iseed', dest='iseed', help='Seed for the pseudorandom number generator')
+    parser.add_option('', '--icutoff', dest='icutoff', help='Number of first bases of the reference sequence to index')
+    parser.add_option('', '--ioldpmap', dest='ioldpmap', help='Use the scheme for mapping joined reference locations to original reference locations used in versions of Bowtie prior to 0.9.8')
+    parser.add_option('', '--indexSettings', dest='index_settings', help='Whether or not indexing options are to be set')
+    (options, args) = parser.parse_args()
+    
+    # index if necessary
+    if options.genomeSource == 'history':
+        # set up commands
+        if options.index_settings =='index_pre_set':
+            indexing_cmds = ''
+        else:
+            try:
+                indexing_cmds = '%s %s %s %s %s %s %s --offrate %s %s %s %s %s %s %s' % \
+                                (('','--noauto')[options.iauto_b=='set'], 
+                                 ('','--packed')[options.ipacked=='packed'],
+                                 ('','--bmax %s'%options.ibmax)[options.ibmax!='None' and options.ibmax>=1], 
+                                 ('','--bmaxdivn %s'%options.ibmaxdivn)[options.ibmaxdivn!='None'],
+                                 ('','--dcv %s'%options.idcv)[options.idcv!='None'], 
+                                 ('','--nodc')[options.inodc=='nodc'],
+                                 ('','--noref')[options.inoref=='noref'], options.ioffrate, 
+                                 ('','--ftabchars %s'%options.iftab)[int(options.iftab)>=0], 
+                                 ('','--ntoa')[options.intoa=='yes'], 
+                                 ('--little','--big')[options.iendian=='big'],
+                                 ('','--seed %s'%options.iseed)[int(options.iseed)>0], 
+                                 ('','--cutoff %s'%options.icutoff)[int(options.icutoff)>0], 
+                                 ('','--oldpmap')[options.ioldpmap=='yes'])
+            except ValueError:
+                indexing_cmds = ''
+                
+        # make temp directory for placement of indices and copy reference file there
+        tmp_dir = tempfile.gettempdir()
+        try:
+            os.system('cp %s %s' % (options.ref, tmp_dir))
+        except Exception, erf:
+            stop_err('Error creating temp directory for indexing purposes\n' + str(erf))
+        options.ref = os.path.join(tmp_dir,os.path.split(options.ref)[1])
+        cmd1 = 'cd %s; bowtie-build %s -f %s %s > /dev/null' % (tmp_dir, indexing_cmds, options.ref, options.ref)
+        try:
+            os.system(cmd1)
+        except Exception, erf:
+            stop_err('Error indexing reference sequence\n' + str(erf))
+    
+    # set up aligning and generate aligning command options
+    # automatically set threads to 8 in both cases
+    if options.params == 'pre_set':
+        aligning_cmds = '-p 8'
+    else:
+        try:
+            aligning_cmds = '%s %s %s %s %s %s %s %s %s %s %s %s %s %s ' \
+                            '%s %s %s %s %s %s %s %s %s %s %s %s %s %s -p 8' % \
+                            (('','-s %s'%options.skip)[options.skip!='None'], 
+                             ('','-u %s'%options.alignLimit)[int(options.alignLimit)>0],
+                             ('','-5 %s'%options.trimH)[int(options.trimH)>=0], 
+                             ('','-3 %s'%options.trimL)[int(options.trimL)>=0], 
+                             ('','-n %s'%options.mismatchSeed)[options.mismatchSeed=='0' or options.mismatchSeed=='1' or options.mismatchSeed=='2' or options.mismatchSeed=='3'], 
+                             ('','-e %s'%options.mismatchQual)[int(options.mismatchQual)>=0], 
+                             ('','-l %s'%options.seedLen)[int(options.seedLen)>=5], 
+                             ('','--nomaqround')[options.rounding=='noRound'],
+                             ('','-v %s'%options.maqSoapAlign)[options.maqSoapAlign!='-1'],
+                             ('','-I %s'%options.minInsert)[options.minInsert!='None'], 
+                             ('','-X %s'%options.maxInsert)[options.maxInsert!='None'], 
+                             ('','--%s'%options.mateOrient)[options.mateOrient!='None'],
+                             ('','--pairtries %s'%options.maxAlignAttempt)[int(options.maxAlignAttempt)>=0],
+                             ('','--nofw')[options.forwardAlign=='noForward'],
+                             ('','--norc')[options.reverseAlign=='noReverse'],
+                             ('','--maxbts %s'%options.maxBacktracks)[options.maxBacktracks!='None' and (options.mismatchSeed=='2' or options.mismatchSeed=='3')], 
+                             ('','-y')[options.tryHard=='doTryHard'],
+                             ('','--chunkmbs %s'%options.threadMem)[options.threadMem!='None' and int(options.threadMem)>=0],
+                             ('','-k %s'%options.valAlign)[options.valAlign!='None' and int(options.valAlign)>=0], 
+                             ('','-a')[options.allValAligns=='doAllValAligns' and int(options.allValAligns)>=0],
+                             ('','-m %s'%options.suppressAlign)[int(options.suppressAlign)>=0], 
+                             ('','--best')[options.best=='doBest'],
+                             ('','--strata')[options.strata=='doStrata'],
+                             ('','-B %s'%options.offbase)[int(options.offbase)>=0],
+                             ('','-z %s'%options.phased)[options.phased!='None'], 
+                             ('','-o %s'%options.offrate)[int(options.offrate)>=0],
+                             ('','--mm')[options.mm=='doMm'], 
+                             ('','--seed %s'%options.seed)[int(options.seed)>=0])
+        except ValueError:
+            aligning_cmds = '-p 8' 
+
+    tmp_out = tempfile.NamedTemporaryFile()
+
+    # prepare actual aligning commands
+    if options.paired == 'paired':
+        cmd2 = 'bowtie %s %s -1 %s -2 %s > %s 2> /dev/null' % (aligning_cmds, options.ref, options.input1, options.input2, tmp_out.name)
+    else:
+        cmd2 = 'bowtie %s %s %s > %s 2> /dev/null' % (aligning_cmds, options.ref, options.input1, tmp_out.name)
+    # prepare command to convert bowtie output to sam and alternative
+    cmd3 = 'bowtie2sam.pl %s > %s' % (tmp_out.name, options.output)
+    cmd4 = 'cp %s %s' % (tmp_out.name, options.output)
+
+    # align
+    try:
+        os.system(cmd2)
+    except Exception, erf:
+        stop_err("Error aligning sequence\n" + str(erf))
+    if len(file(tmp_out.name,'r').read()) > 0:
+        #convert 
+        try:
+            os.system(cmd3)
+        except Exception, erf:
+            stop_err('Error converting output to sam format\n' + str(erf))
+    else:
+        try:
+            os.system(cmd4)
+            sys.stdout.write('Alignment file contained no data')
+        except Exception, erf:
+            stop_err('Error producing alignment file. File contained no data.\n' + str(erf))
+
+if __name__=="__main__": __main__()
diff -r 032478337b82 -r 355b6844b123 tools/sr_mapping/bowtie_wrapper.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/sr_mapping/bowtie_wrapper.xml	Fri Sep 11 15:04:53 2009 -0400
@@ -0,0 +1,556 @@
+<tool id="bowtie_wrapper" name="Bowtie" version="1.0.0">
+  <description> fast alignment of reads against reference sequence </description>
+  <command interpreter="python">
+    bowtie_wrapper.py 
+    --input1=$singlePaired.input1
+    #if $singlePaired.sPaired == "paired":
+     --input2=$singlePaired.input2
+    #else:
+     --input2="None"
+    #end if
+    --output=$output
+    --paired=$singlePaired.sPaired
+    --genomeSource=$refGenomeSource.genomeSource
+    #if $refGenomeSource.genomeSource == "history":
+     --ref=$refGenomeSource.ownFile
+    #else:
+     --ref=$refGenomeSource.indices.value
+    #end if
+    --params=$singlePaired.params.settings_type
+    #if $singlePaired.params.settings_type == "full":
+     --skip=$singlePaired.params.skip
+     --alignLimit=$singlePaired.params.alignLimit
+     --trimH=$singlePaired.params.trimH
+     --trimL=$singlePaired.params.trimL
+     --mismatchSeed=$singlePaired.params.mismatchSeed
+     --mismatchQual=$singlePaired.params.mismatchQual
+     --seedLen=$singlePaired.params.seedLen
+     --rounding=$singlePaired.params.rounding
+     --maqSoapAlign=$singlePaired.params.maqSoapAlign
+     --tryHard=$singlePaired.params.tryHard
+     --valAlign=$singlePaired.params.valAlign
+     --allValAligns=$singlePaired.params.allValAligns
+     --suppressAlign=$singlePaired.params.suppressAlign
+     --offbase=$singlePaired.params.offbase
+     --offrate=$singlePaired.params.offrate
+     --mm=$singlePaired.params.mm
+     --seed=$singlePaired.params.seed
+     --best=$singlePaired.params.bestOption.best
+     #if $singlePaired.params.bestOption.best == "doBest":
+      --maxBacktracks=$singlePaired.params.bestOption.maxBacktracks
+      --threadMem=$singlePaired.params.bestOption.threadMem
+      --strata=$singlePaired.params.bestOption.strata
+      --phased="None"
+     #else:
+      --maxBacktracks="None"
+      --threadMem="None"
+      --strata="None"
+      #if $singlePaired.sPaired =="single":
+       --phased=$singlePaired.params.bestOption.phased
+      #else:
+       --phased="None"
+      #end if
+     #end if
+     #if $singlePaired.sPaired == "single":
+      --minInsert="None"
+      --maxInsert="None"
+      --mateOrient="None"
+      --maxAlignAttempt="None"
+      --forwardAlign="None"
+      --reverseAlign="None"
+     #else:
+      --minInsert=$singlePaired.params.minInsert
+      --maxInsert=$singlePaired.params.maxInsert
+      --mateOrient=$singlePaired.params.mateOrient
+      --maxAlignAttempt=$singlePaired.params.maxAlignAttempt
+      --forwardAlign=$singlePaired.params.forwardAlign
+      --reverseAlign=$singlePaired.params.reverseAlign
+     #end if
+    #else
+     --skip="None"
+     --alignLimit="None"
+     --trimH="None"
+     --trimL="None"
+     --mismatchSeed="None"
+     --mismatchQual="None"
+     --seedLen="None"
+     --rounding="None"
+     --maqSoapAlign="None"
+     --tryHard="None"
+     --valAlign="None"
+     --allValAligns="None"
+     --suppressAlign="None"
+     --offbase="None"
+     --best="None"
+     --maxBacktracks="None"
+     --threadMem="None"
+     --strata="None"
+     --minInsert="None"
+     --maxInsert="None"
+     --mateOrient="None"
+     --maxAlignAttempt="None"
+     --forwardAlign="None"
+     --reverseAlign="None"
+     --phased="None"
+     --offrate="None"
+     --mm="None"
+     --seed="None"
+    #end if
+    #if $refGenomeSource.genomeSource == "history":
+     --dbkey=$dbkey
+    #else:
+     --dbkey="None"
+    #end if
+    #if $refGenomeSource.genomeSource == "history":
+     --indexSettings=$refGenomeSource.indexParams.index_settings
+    #else:
+     --indexSettings="None"
+    #end if
+    #if $refGenomeSource.genomeSource == "history" and $refGenomeSource.indexParams.index_settings == "index_full":
+     --iauto_b=$refGenomeSource.indexParams.auto_behavior.auto_b
+     #if $refGenomeSource.indexParams.auto_behavior.auto_b == "set":
+      --ipacked=$refGenomeSource.indexParams.auto_behavior.packed
+      --ibmax=$refGenomeSource.indexParams.auto_behavior.bmax
+      --ibmaxdivn=$refGenomeSource.indexParams.auto_behavior.bmaxdivn
+      --idcv=$refGenomeSource.indexParams.auto_behavior.dcv
+     #else:
+      --ipacked="None"
+      --ibmax="None"
+      --ibmaxdivn="None"
+      --idcv="None"
+     #end if
+     --inodc=$refGenomeSource.indexParams.nodc
+     --inoref=$refGenomeSource.indexParams.noref
+     --ioffrate=$refGenomeSource.indexParams.offrate
+     --iftab=$refGenomeSource.indexParams.ftab
+     --intoa=$refGenomeSource.indexParams.ntoa
+     --iendian=$refGenomeSource.indexParams.endian
+     --iseed=$refGenomeSource.indexParams.seed
+     --icutoff=$refGenomeSource.indexParams.cutoff
+     --ioldpmap=$refGenomeSource.indexParams.oldpmap
+    #else:
+     --iauto_b="None"
+     --ipacked="None"
+     --ibmax="None"
+     --ibmaxdivn="None"
+     --idcv="None"
+     --inodc="None"
+     --inoref="None"
+     --ioffrate="None"
+     --iftab="None"
+     --intoa="None"
+     --iendian="None"
+     --iseed="None"
+     --icutoff="None"
+     --ioldpmap="None"
+    #end if
+  </command>
+  <inputs>
+    <conditional name="refGenomeSource">
+      <param name="genomeSource" type="select" label="Will you select a reference genome from your history or use a built-in index?" help="Built-ins were indexed using default options">
+        <option value="indexed">Use a built-in index</option>
+        <option value="history">Use one from the history</option>
+      </param>
+      <when value="indexed">
+    	<param name="indices" type="select" label="Select a reference genome">
+  	      <options from_file="bowtie_indices.loc">
+  	        <column name="value" index="1" />
+  	        <column name="name" index="0" />
+  	        <filter type="sort_by" column="0" />
+  	      </options>
+  	    </param>
+  	  </when>
+      <when value="history">
+        <param name="ownFile" type="data" format="fasta" metadata_name="dbkey" label="Select a reference genome" />
+        <conditional name="indexParams">
+          <param name="index_settings" type="select" label="Choose whether to use default options or to set your own">
+            <option value="index_pre_set">Commonly Used</option>
+            <option value="index_full">Full Parameter List</option>
+          </param> 
+          <when value="index_pre_set" />
+          <when value="index_full">
+            <conditional name="auto_behavior">
+              <param name="auto_b" type="select" label="Choose to use automatic or specified behavior for some parameters (-a)" help="Allows you to set --packed, --bmax, --bmaxdivn, and --dcv">
+                <option value="auto">Automatic behavior</option>
+                <option value="set">Set values (sets --noauto and allows others to be set)</option>
+              </param>
+              <when value="auto" />
+              <when value="set">
+                <param name="packed" type="select" label="Whether or not to use a packed representation for DNA strings (-p)">
+                  <option value="unpacked">Use regular representation</option>
+                  <option value="packed">Use packed representation</option>
+                </param>
+                <param name="bmax" type="integer" value="-1" label="Maximum number of suffixes allowed in a block (--bmax)" help="-1 for not specified. Must be at least 1" />
+                <param name="bmaxdivn" type="integer" value="4" label="Maximum number of suffixes allowed in a block as a fraction of the length of the reference (--bmaxdivn)" />
+                <param name="dcv" type="integer" value="1024" label="The period for the difference-cover sample (--dcv)" />
+              </when>
+            </conditional>
+            <param name="nodc" type="select" label="Whether or not to disable the use of the difference-cover sample (--nodc)" help="Suffix sorting becomes quadratic-time in the worst case (a very repetetive reference)">
+              <option value="dc">Use difference-cover sample</option>
+              <option value="nodc">Disable difference-cover sample</option>
+            </param>
+            <param name="noref" type="select" label="Whether or not to build the part of the reference index used only in paired-end alignment (-r)">
+              <option value="ref">Build all index files</option>
+              <option value="noref">Do not build paired-end alignment index files</option>
+            </param>
+            <param name="offrate" type="integer" value="5" label="How many rows get marked during annotation of some or all of the Burrows-Wheeler rows (-o)" />
+            <param name="ftab" type="integer" value="10" label="The size of the lookup table used to calculate an initial Burrows-Wheeler range with respect to the first n characters of the query (-t)" help="ftab is 4^(n+1) bytes" />
+            <param name="ntoa" type="select" label="Whether or not to convert Ns in the reference sequence to As (--ntoa)">
+              <option value="no">Do not convert Ns</option>
+              <option value="yes">Convert Ns to As</option>
+            </param>
+            <param name="endian" type="select" label="Endianness to use when serializing integers to the index file (--big/--little)" help="Little is most appropriate for Intel- and AMD-based architecture">
+              <option value="little">Little</option>
+              <option value="big">Big</option>
+            </param> 
+            <param name="seed" type="integer" value="-1" label="Seed for the pseudorandom number generator (--seed)" help="Use -1 to use default" />
+            <param name="cutoff" type="integer" value="-1" label="Number of first bases of the reference sequence to index (--cutoff)" help="Use -1 to use default" />
+            <param name="oldpmap" type="select" label="Use the scheme for mapping joined reference locations to original reference locations used in versions of Bowtie prior to 0.9.8 (--oldpmap)" help="The old scheme uses padding and the new one doesn't">
+              <option value="no">Use the new scheme</option>
+              <option value="yes">Use the old scheme</option>
+            </param> 
+          </when> <!-- index_full -->
+        </conditional>
+      </when>
+ 	</conditional> <!-- refGenomeSource -->
+    <conditional name="singlePaired">
+      <param name="sPaired" type="select" label="Is this library mate-paired?">
+        <option value="single">Single-end</option>
+        <option value="paired">Paired-end</option>
+      </param>
+      <when value="single">
+        <param name="input1" type="data" format="fastqsanger" label="FASTQ file" />
+        <conditional name="params">
+          <param name="settings_type" type="select" label="Bowtie settings to use" help="For most mapping needs use Commonly used settings. If you want full control use Full parameter list">
+		    <option value="pre_set">Commonly used</option>
+   		    <option value="full">Full parameter list</option>
+	      </param>
+          <when value="pre_set" />
+          <when value="full">
+            <param name="skip" type="integer" value="0" label="Skip the first n reads (-s)" />  
+            <param name="alignLimit" type="integer" value="-1" label="Only align the first n reads (-u)" help="-1 for off" />  
+            <param name="trimH" type="integer" value="0" label="Trim n bases from high-quality (left) end of each read before alignment (-5)" />
+            <param name="trimL" type="integer" value="0" label="Trim n bases from low-quality (right) end of each read before alignment (-3)" />
+            <param name="mismatchSeed" type="integer" value="2" label="Maximum number of mismatches permitted in the seed (-n)" help="May be 0, 1, 2, or 3" />
+            <param name="mismatchQual" type="integer" value="70" label="Maximum permitted total of quality values at mismatched read positions (-e)" />
+            <param name="seedLen" type="integer" value="28" label="Seed length (-l)" help="Minimum value is 5" />
+            <param name="rounding" type="select" label="Whether or not to round to the nearest 10 and saturating at 30 (--nomaqround)">
+              <option value="round">Round to nearest 10</option>
+              <option value="noRound">Do not round to nearest 10</option>
+            </param>
+            <param name="maqSoapAlign" type="integer" value="-1" label="Number of mismatches for SOAP-like alignment policy (-v)" help="-1 for default MAQ-like alignment policy" />
+            <param name="tryHard" type="select" label="Whether or not to try as hard as possible to find valid alignments when they exist (-y)" help="Tryhard mode is much slower than regular mode">
+              <option value="noTryHard">Do not try hard</option>
+              <option value="doTryHard">Try hard</option>
+            </param>
+            <param name="valAlign" type="integer" value="1" label="Report up to n valid arguments per read (-k)" />
+            <param name="allValAligns" type="select" label="Whether or not to report all valid alignments per read (-a)">
+              <option value="noAllValAligns">Do not report all valid alignments</option>
+              <option value="doAllValAligns">Report all valid alignments</option>
+            </param>
+            <param name="suppressAlign" type="integer" value="-1" label="Suppress all alignments for a read if more than n reportable alignments exist (-m)" help="-1 for no limit" />
+            <param name="offbase" type="integer" value="0" label="Number the first base of a reference sequence as n when outputting alignments (-B)" />
+            <conditional name="bestOption">
+              <param name="best" type="select" label="Whether or not to make Bowtie guarantee that reported singleton alignments are 'best' in terms of stratum and in terms of the quality values at the mismatched positions (--best)" help="Removes all strand bias. Only affects which alignments are reported by Bowtie. Runs slower with best option">
+                <option value="noBest">Do not use best</option>
+                <option value="doBest">Use best</option>
+              </param>
+              <when value="noBest">
+                <param name="maxBacktracks" type="integer" value="125" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
+                <param name="phased" type="select" label="Whether or not it should alternate between using the forward and mirror indexes in a series of phases so that only half of the index is resident in memory at one time (-z)">
+                  <option value="noPhased">Don't alternate</option>
+                  <option value="doPhased">Do alternate</option>
+                </param>
+              </when>
+              <when value="doBest">
+                <param name="maxBacktracks" type="integer" value="800" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
+                <param name="threadMem" type="integer" value="32" label="Number of megabytes of memory a given thread is given to store path descriptors in best mode (--chunkmbs)" help="If running in best mode, and you run out of memory, try adjusting this" />
+                <param name="strata" type="select" label="Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable (--strata)">
+                  <option value="noStrata">Do not use strata option</option>
+                  <option value="doStrata">Use strata option</option>
+                </param>
+              </when>
+            </conditional> <!-- bestOption -->
+            <param name="offrate" type="integer" value="-1" label="Override the offrate of the index to n (-o)" help="-1 for default" />
+            <param name="mm" type="select" label="Whether or not to use memory-mapped I/O to load the index (--m)">
+              <option value="noMm">Use POSIX/C file I/O</option>
+              <option value="doMm">Use memory-mapped I/O</option>
+            </param>
+            <param name="seed" type="integer" value="-1" label="Seed for pseudo-random number generator (--seed)" help="-1 for default" />
+          </when> <!-- full -->
+        </conditional> <!-- params -->
+      </when> <!-- single -->
+      <when value="paired">
+        <param name="input1" type="data" format="fastqsanger" label="Forward FASTQ file" />
+        <param name="input2" type="data" format="fastqsanger" label="Reverse FASTQ file" />
+        <conditional name="params">
+          <param name="settings_type" type="select" label="BWA settings to use" help="For most mapping needs use Commonly used settings. If you want full control use Full parameter list">
+		    <option value="pre_set">Commonly used</option>
+   		    <option value="full">Full parameter list</option>
+	      </param>
+          <when value="pre_set" />
+          <when value="full">
+            <param name="skip" type="integer" value="0" label="Skip the first n pairs (-s)" />  
+            <param name="alignLimit" type="integer" value="-1" label="Only align the first n pairs (-u)" help="-1 for off" />  
+            <param name="trimH" type="integer" value="0" label="Trim n bases from high-quality (left) end of each read before alignment (-5)" />
+            <param name="trimL" type="integer" value="0" label="Trim n bases from low-quality (right) end of each read before alignment (-3)" />
+            <param name="mismatchSeed" type="integer" value="2" label="Maximum number of mismatches permitted in the seed (-n)" help="May be 0, 1, 2, or 3" />
+            <param name="mismatchQual" type="integer" value="70" label="Maximum permitted total of quality values at mismatched read positions (-e)" />
+            <param name="seedLen" type="integer" value="28" label="Seed length (-l)" help="Minimum value is 5" />
+            <param name="rounding" type="select" label="Whether or not to round to the nearest 10 and saturating at 30 (--nomaqround)">
+              <option value="round">Round to nearest 10</option>
+              <option value="noRound">Do not round to nearest 10</option>
+            </param>
+            <param name="maqSoapAlign" type="integer" value="-1" label="Number of mismatches for SOAP-like alignment policy (-v)" help="-1 for default MAQ-like alignment policy" />
+            <param name="minInsert" type="integer" value="0" label="Minimum insert size for valid paired-end alignments (-I)" />
+            <param name="maxInsert" type="integer" value="250" label="Maximum insert size for valid paired-end alignments (-X)" />
+            <param name="mateOrient" type="select" label="The upstream/downstream mate orientation for valid paired-end alignment against the forward reference strand (--fr/--rf/--ff)">
+              <option value="fr">FR (for Illumina)</option>
+              <option value="rf">RF</option>
+              <option value="ff">FF</option>
+            </param>
+            <param name="maxAlignAttempt" type="integer" value="100" label="Maximum number of attempts Bowtie will make to match an alignment for one mate with an alignment for the opposite mate (--pairtries)" />
+            <param name="forwardAlign" type="select" label="Choose whether or not to attempt to align the forward reference strand (--nofw)">
+              <option value="forward">Align against the forward reference strand</option>
+              <option value="noForward">Do not align against the forward reference strand</option>
+            </param>
+            <param name="reverseAlign" type="select" label="Choose whether or not to align against the reverse-complement reference strand (--norc)">
+              <option value="reverse">Align against the reverse-complement reference strand</option>
+              <option value="noReverse">Do not align against the reverse-complement reference strand</option>
+            </param>
+            <param name="tryHard" type="select" label="Whether or not to try as hard as possible to find valid alignments when they exist (-y)" help="Tryhard mode is much slower than regular mode">
+              <option value="noTryHard">Do not try hard</option>
+              <option value="doTryHard">Try hard</option>
+            </param>
+            <param name="valAlign" type="integer" value="1" label="Report up to n valid arguments per pair (-k)" />
+            <param name="allValAligns" type="select" label="Whether or not to report all valid alignments per pair (-a)">
+              <option value="noAllValAligns">Do not report all valid alignments</option>
+              <option value="doAllValAligns">Report all valid alignments</option>
+            </param>
+            <param name="suppressAlign" type="integer" value="-1" label="Suppress all alignments for a pair if more than n reportable alignments exist (-m)" help="-1 for no limit" />
+            <param name="offbase" type="integer" value="0" label="Number the first base of a reference sequence as n when outputting alignments (-B)" />
+            <conditional name="bestOption">
+              <param name="best" type="select" label="Whether or not to make Bowtie guarantee that reported singleton alignments are 'best' in terms of stratum and in terms of the quality values at the mismatched positions (--best)" help="Removes all strand bias. Only affects which alignments are reported by Bowtie. Runs slower with best option">
+                <option value="noBest">Do not use best</option>
+                <option value="doBest">Use best</option>
+              </param>
+              <when value="noBest">
+                <param name="maxBacktracks" type="integer" value="125" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
+              </when>
+              <when value="doBest">
+                <param name="maxBacktracks" type="integer" value="800" label="Maximum number of backtracks permitted when aligning a read (--maxbts)" />
+                <param name="threadMem" type="integer" value="32" label="Number of megabytes of memory a given thread is given to store path descriptors in best mode (--chunkmbs)" help="If running in best mode, and you run out of memory, try adjusting this" />
+                <param name="strata" type="select" label="Whether or not to report only those alignments that fall in the best stratum if many valid alignments exist and are reportable (--strata)">
+                  <option value="noStrata">Do not use strata option</option>
+                  <option value="doStrata">Use strata option</option>
+                </param>
+              </when>
+            </conditional>
+            <param name="offrate" type="integer" value="-1" label="Override the offrate of the index to n -o)" help="-1 for default" />
+            <param name="mm" type="select" label="Whether or not to use memory-mapped I/O to load the index (--mm)">
+              <option value="noMm">Use POSIX/C file I/O</option>
+              <option value="doMm">Use memory-mapped I/O</option>
+            </param>
+            <param name="seed" type="integer" value="-1" label="Seed for pseudo-random number generator (--seed)" help="-1 for default" />
+          </when> <!-- full -->
+        </conditional> <!-- params -->
+      </when> <!-- paired -->
+    </conditional> <!-- singlePaired -->
+  </inputs>
+  <outputs>
+    <data format="sam" name="output" />
+  </outputs>
+  <tests>
+    <test>
+      <param name="genomeSource" value="indexed" />
+      <param name="indices" value="chrM" />
+      <param name="sPaired" value="single" />
+      <param name="input1" ftype="fastqsanger" value="bowtie_in1.fastq" />
+      <param name="settings_type" value="pre_set" />
+      <output name="output" ftype="sam" file="bowtie_out1.sam" />
+    </test>
+    <test>
+      <param name="genomeSource" value="history" />
+      <param name="ownFile" value="chrM.fa" />
+      <param name="index_settings" value="index_pre_set" />
+      <param name="sPaired" value="paired" />
+      <param name="input1" ftype="fastqsanger" value="bowtie_in2.fastq" />
+      <param name="input2" ftype="fastqsanger" value="bowtie_in3.fastq" />
+      <param name="settings_type" value="pre_set" />
+      <output name="output" ftype="sam" file="bowtie_out2.sam" />
+    </test>
+    <test>
+      <param name="genomeSource" value="history" />
+      <param name="ownFile" value="chrM.fa" />
+      <param name="index_settings" value="index_full" />
+      <param name="auto_b" value="set" />
+      <param name="packed" value="unpacked" />
+      <param name="bmax" value="-1" />
+      <param name="bmaxdivn" value="4" />
+      <param name="dcv" value="2048" />
+      <param name="nodc" value="dc" />
+      <param name="noref" value="noref" />
+      <param name="offrate" value="6" />
+      <param name="ftab" value="10" />
+      <param name="ntoa" value="yes" />
+      <param name="endian" value="little" />
+      <param name="seed" value="-1" />
+      <param name="cutoff" value="-1" />
+      <param name="oldpmap" value="no" />
+      <param name="sPaired" value="single" />
+      <param name="input1" ftype="fastqsanger" value="bowtie_in1.fastq" />
+      <param name="settings_type" value="pre_set" />
+      <output name="output" ftype="sam" file="bowtie_out1.sam" />
+    </test>  
+    <test>
+      <param name="genomeSource" value="indexed" />
+      <param name="indices" value="chrM" />
+      <param name="sPaired" value="paired" />
+      <param name="input1" ftype="fastqsanger" value="bowtie_in2.fastq" />
+      <param name="input2" ftype="fastqsanger" value="bowtie_in3.fastq" />
+      <param name="settings_type" value="full" />
+      <param name="skip" value="0" />
+      <param name="alignLimit" value="-1" />
+      <param name="trimL" value="0" />
+      <param name="trimH" value="0" />
+      <param name="mismatchSeed" value="3" />
+      <param name="mismatchQual" value="50" />
+      <param name="seedLen" value="10" />
+      <param name="rounding" value="round" />
+      <param name="maqSoapAlign" value="-1" />
+      <param name="minInsert" value="0" />
+      <param name="maxInsert" value="250" />
+      <param name="mateOrient" value="fr" />
+      <param name="maxAlignAttempt" value="100" />
+      <param name="forwardAlign" value="forward" />
+      <param name="reverseAlign" value="reverse" />
+      <param name="tryHard" value="doTryHard" />
+      <param name="valAlign" value="1" />
+      <param name="allValAligns" value="noAllValAligns" />
+      <param name="suppressAlign" value="-1" />
+      <param name="offbase" value="0" />
+      <param name="best" value="doBest" />
+      <param name="maxBacktracks" value="800" />
+      <param name="threadMem" value="32" />
+      <param name="strata" value="noStrata" />
+      <param name="offrate" value="-1" />
+      <param name="mm" value="noMm" />
+      <param name="seed" value="403" />
+      <output name="output" ftype="sam" file="bowtie_out2.sam" />
+    </test>
+  </tests> 
+  <help>
+
+**What it does**
+
+Bowtie_ is a short read aligner designed to be ultrafast and memory-efficient. Reads can be as long as 1024 base pairs, though shorter is better. Bowtie produces a specific output format which is converted to SAM by this tool. 
+
+.. _Bowtie: http://bowtie-bio.sourceforge.net/index.shtml
+
+------
+
+**Input formats**
+
+Bowtie accepts files in Sanger FASTQ format. 
+
+------
+
+**Outputs**
+
+The output is in SAM format, and has the following columns::
+
+  1  QNAME  -  Query (pair) NAME
+  2  FLAG   -  bitwise FLAG
+  3  RNAME  -  Reference sequence NAME
+  4  POS    -  1-based leftmost POSition/coordinate of clipped sequence
+  5  MAPQ   -  MAPping Quality (Phred-scaled)
+  6  CIGAR  -  extended CIGAR string
+  7  MRNM   -  Mate Reference sequence NaMe ('=' if same as RNAME)
+  8  MPOS   -  1-based Mate POSition
+  9  ISIZE  -  Inferred insert SIZE
+  10 SEQ    -  query SEQuence on the same strand as the reference
+  11 QUAL   -  query QUALity (ASCII-33 gives the Phred base quality)
+  12 OPT    -  variable OPTional fields in the format TAG:VTYPE:VALU
+  
+The flags are as follows::
+
+  Flag    -  Description
+  0x0001  -  the read is paired in sequencing
+  0x0002  -  the read is mapped in a proper pair
+  0x0004  -  the query sequence itself is unmapped
+  0x0008  -  the mate is unmapped
+  0x0010  -  strand of the query (1 for reverse)
+  0x0020  -  strand of the mate
+  0x0040  -  the read is the first read in a pair
+  0x0080  -  the read is the second read in a pair
+  0x0100  -  the alignment is not primary
+
+It looks like this (scroll sideways to see the entire example)::
+
+  QNAME	FLAG	RNAME	POS	MAPQ	CIAGR	MRNM	MPOS	ISIZE	SEQ	QUAL	OPT
+  HWI-EAS91_1_30788AAXX:1:1:1761:343	4	*	0	0	*	*	0	0	AAAAAAANNAAAAAAAAAAAAAAAAAAAAAAAAAAACNNANNGAGTNGNNNNNNNGCTTCCCACAGNNCTGG	hhhhhhh;;hhhhhhhhhhh^hOhhhhghhhfhhhgh;;h;;hhhh;h;;;;;;;hhhhhhghhhh;;Phhh
+  HWI-EAS91_1_30788AAXX:1:1:1578:331	4	*	0	0	*	*	0	0	GTATAGANNAATAAGAAAAAAAAAAATGAAGACTTTCNNANNTCTGNANNNNNNNTCTTTTTTCAGNNGTAG	hhhhhhh;;hhhhhhhhhhhhhhhhhhhhhhhhhhhh;;h;;hhhh;h;;;;;;;hhhhhhhhhhh;;hhVh
+
+-------
+
+**Bowtie settings**
+
+All of the options have a default value. You can change any of them. Most of the options in Bowtie have been implemented here.
+
+------
+
+**Bowtie parameter list**
+
+This is an exhaustive list of Bowtie options:
+
+For indexing (bowtie-build)::
+	-a                      No auto behavior. Disable the default behavior where bowtie automatically selects values for --bmax/--dcv/--packed parameters according to the memory available. [off]
+	-p                      Packing. Use a packed representation for DNA strings. [auto] 
+	--bmax <int>      Suffix maximum. The maximum number of suffixes allowed in a block. [auto]
+	--bmaxdivn <int>  Suffix maximum fraction. The maximum number of suffixes allowed in a block expressed as a fraction of the length of the reference. [4]
+	--dcv <int>       Difference-cover sample. Use <int> as the period for the difference-cover sample. [1024]
+	--nodc <int>      No difference-cover sample. Disable the difference-cover sample. [off]
+	-r                      No reference indexes. Do not build the NAME.3.ebwt and NAME.4.ebwt portions of the index, used only for paired-end alignment. [off]
+	-o                      Offrate. How many Burrows-Wheeler rows get marked by the indexer. The indexer will mark every 2^<int> rows. The marked rows correspond to rows on the genome. [5]
+	-t <int>          Ftab. The lookup table used to calculate an initial Burrows-Wheeler range with respect to the first <int> characters of the query. Ftab is 4^<int>+1 bytes. [10]
+	--ntoa                  N conversion. Convert Ns to As before building the index. Otherwise, Ns are simply excluded from the index and Bowtie will not find alignments that overlap them. [off]
+	--big                   Endianness. Endianness to use when serializing integers to the index file. [off]
+	--little                Endianness. [--little]
+	--seed <int>      Random seed. Use <int> as the seed for the pseudo-random number generator. [off]
+	--cutoff <int>    Cutoff. Index only the first <int> bases of the reference sequences (cumulative across sequences) and ignore the rest. [off]
+	--oldpmap               Use old mapping scheme. Use the padding-based scheme from Bowtie versions before 0.9.8 instead of the current scheme. [off]
+
+For aligning (bowtie)::
+	-s <int>           Skip. Do not align the first <int> reads or pairs in the input. [off]
+	-u <int>           Align limit. Only align the first <int> reads/pairs from the input. [no limit]
+	-5 <int>           High-quality trim. Trim <int> bases from the high-quality (left) end of each read before alignment. [0]
+	-3 <int>           Low-quality trim. Trim <int> bases from the low-quality (right) end of each read before alignment. [0]
+	-n <int>           Mismatch seed. Maximum number of mismatches permitted in the seed (defined with seed length option). Can be 0, 1, 2, or 3. [2]
+	-e <int>           Mismatch quality. Maximum permitted total of quality values at mismatched read positions. Bowtie rounds quality values to the nearest 10 and saturates at 30. [70]
+	-l <int>           Seed length. The number of bases on the high-quality end of the read to which the -n ceiling applies. Must be at least 5. [28]
+	--nomaqround             Suppress MAQ rounding. Values are internally rounded to the nearest 10 and saturate at 30. This options turns off that rounding. [off] 
+	-v <int>           MAQ- or SOAP-like alignment policy. This option turns off the default MAQ-like alignment policy in favor of a SOAP-like one. End-to-end alignments with at most <int> mismatches. [off]
+	-I <int>           Minimum insert. The minimum insert size for valid paired-end alignments. Does checking on untrimmed reads if -5 or -3 is used. [0]
+	--fr                     Mate orientation. The upstream/downstream mate orientations for a valid paired-end alignment against the forward reference strand. [--fr]
+	--rf                     Mate orientation. [off]
+	--ff                     Mate orientation. [off]
+	-X <int>           Maximum insert. The maximum insert size for valid paired-end alignments. Does checking on untrimmed reads if -5 or -3 is used. [250]
+	--pairtries <int>  Maximum alignment attempts for paired-end data. [100] 
+	--nofw                   No forward aligning. Choosing this option means that Bowtie will not attempt to align against the forward reference strand. [off]
+	--norc                   No reverse-complement aligning. Setting this will mean that Bowtie will not attempt to align against the reverse-complement reference strand. [off]
+	--maxbts <int>     Maximum backtracks. The maximum number of backtracks permitted when aligning a read in -n 2 or -n 3 mode. [125 without --best] [800 with --best]
+	-y                       Try hard. Try as hard as possible to find valid alignments when they exist, including paired-end alignments. [off]
+	--chunkmbs <int>   Thread memory. The number of megabytes of memory a given thread is given to store path descriptors in --best mode. [32]
+	-k <int>           Valid alignments. The number of valid alignments per read or pair. [off] 
+	-a                       All valid alignments. Choosing this means that all valid alignments per read or pair will be reported. [off]
+	-m <int>           Suppress alignments. Suppress all alignments for a particular read or pair if more than <int> reportable alignments exist for it. [no limit]
+	--best                   Best mode. Make Bowtie guarantee that reported singleton alignments are "best" in terms of stratum (the number of mismatches) and quality values at mismatched position. [off]
+	--strata                 Best strata. When running in best mode, report alignments that fall into the best stratum if there are ones falling into more than one. [off]
+	-B <int>           First base number. When outputting alignments, number the first base of a reference sequence as <int>. [0]
+	-z <int>           Phased. Alternate between using the forward and mirror indexes in a series of phases such that only one half of the index is resident in memory at one time. Cannot be used with paired-end alignment. [off]
+	-o <int>           Offrate override. Override the offrate of the index with <int>. Some row markings are discarded when index read into memory. <int> must be greater than the value used to build the index (default: 5). [off]
+	--mm                     I/O for index loading. Choosing this option means that memory-mapped I/O will be used to load the index instead of the normal POSIX/C file I/O. Allows memory-efficient parallelization where using -p is not desirable. [off]
+	--seed <int>       Random seed. Use <int> as the seed for the pseudo-random number generator. [off]
+
+  </help>
+</tool>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/f2af04af3caa
changeset: 2685:f2af04af3caa
user:      Kanwei Li <kanwei(a)gmail.com>
date:      Fri Sep 11 16:09:02 2009 -0400
description:
Add tool_conf.xml.main that was removed
1 file(s) affected in this change:
tool_conf.xml.main
diffs (267 lines):
diff -r 355b6844b123 -r f2af04af3caa tool_conf.xml.main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tool_conf.xml.main	Fri Sep 11 16:09:02 2009 -0400
@@ -0,0 +1,263 @@
+<?xml version="1.0"?>
+<toolbox>
+  <section name="Get Data" id="getext">
+    <tool file="data_source/upload.xml"/>
+    <tool file="data_source/ucsc_tablebrowser.xml" />
+    <tool file="data_source/ucsc_tablebrowser_archaea.xml" />
+    <tool file="data_source/microbial_import.xml" />
+    <tool file="data_source/biomart.xml" />
+    <tool file="data_source/gramene_mart.xml" />
+    <tool file="data_source/flymine.xml" />
+    <tool file="data_source/encode_db.xml" />
+    <tool file="data_source/epigraph_import.xml" />
+  </section>
+  <section name="Send Data" id="send">
+    <tool file="data_destination/epigraph.xml" />
+  </section>
+  <section name="ENCODE Tools" id="EncodeTools">
+    <tool file="encode/gencode_partition.xml" />
+    <tool file="encode/random_intervals.xml" />
+  </section>
+  <section name="Lift-Over" id="liftOver">
+    <tool file="extract/liftOver_wrapper.xml" />
+  </section>
+  <section name="Text Manipulation" id="textutil">
+    <tool file="filters/fixedValueColumn.xml" />
+    <tool file="stats/column_maker.xml" />
+    <tool file="filters/catWrapper.xml" />
+    <tool file="filters/condense_characters.xml" />
+    <tool file="filters/convert_characters.xml" />
+    <tool file="filters/CreateInterval.xml" />
+    <tool file="filters/cutWrapper.xml" />
+    <tool file="filters/changeCase.xml" />
+    <tool file="filters/pasteWrapper.xml" />
+    <tool file="filters/remove_beginning.xml" />
+    <tool file="filters/headWrapper.xml" />
+    <tool file="filters/tailWrapper.xml" />
+  </section>
+  <section name="Convert Formats" id="convert">
+    <tool file="filters/bed2gff.xml" />
+    <tool file="fasta_tools/fasta_to_tabular.xml" />
+    <tool file="filters/gff2bed.xml" />
+    <tool file="maf/maf_to_bed.xml" />
+    <tool file="maf/maf_to_fasta.xml" />
+    <tool file="fasta_tools/tabular_to_fasta.xml" />
+  </section>
+  <section name="FASTA manipulation" id="fasta_manipulation">
+    <tool file="fasta_tools/fasta_compute_length.xml" />
+    <tool file="fasta_tools/fasta_filter_by_length.xml" />
+    <tool file="fasta_tools/fasta_concatenate_by_species.xml" />
+    <tool file="fasta_tools/fasta_to_tabular.xml" />
+    <tool file="fasta_tools/tabular_to_fasta.xml" />
+  </section>
+  <section name="Filter and Sort" id="filter">
+    <tool file="stats/filtering.xml" />
+    <tool file="filters/sorter.xml" />
+    <tool file="filters/grep.xml" />
+  </section>
+  <section name="Join, Subtract and Group" id="group">
+    <tool file="filters/joiner.xml" />
+    <tool file="filters/compare.xml"/>
+    <tool file="new_operations/subtract_query.xml"/>
+    <tool file="stats/grouping.xml" />   
+  </section>
+  <section name="Extract Features" id="features">
+    <tool file="filters/ucsc_gene_bed_to_exon_bed.xml" />
+    <tool file="extract/extract_GFF_Features.xml" />
+  </section>
+  <section name="Fetch Sequences" id="fetchSeq">
+    <tool file="extract/extract_genomic_dna.xml" />
+  </section>
+  <section name="Fetch Alignments" id="fetchAlign">
+    <tool file="maf/interval2maf_pairwise.xml" />
+    <tool file="maf/interval2maf.xml" />
+    <tool file="maf/interval_maf_to_merged_fasta.xml" />
+    <tool file="maf/genebed_maf_to_fasta.xml"/>
+    <tool file="maf/maf_stats.xml"/>
+    <tool file="maf/maf_thread_for_species.xml"/>
+    <tool file="maf/maf_limit_to_species.xml"/>
+    <tool file="maf/maf_limit_size.xml"/>
+    <tool file="maf/maf_by_block_number.xml"/>
+    <tool file="maf/maf_filter.xml"/>
+    <!--    
+    <tool file="maf/maf_reverse_complement.xml"/>
+    -->
+  </section>
+  <section name="Get Genomic Scores" id="scores">
+    <tool file="stats/wiggle_to_simple.xml" />
+    <tool file="stats/aggregate_binned_scores_in_intervals.xml" />
+    <tool file="extract/phastOdds/phastOdds_tool.xml" />
+  </section>
+  <section name="Operate on Genomic Intervals" id="bxops">
+  	<tool file="new_operations/intersect.xml" />  
+    <tool file="new_operations/subtract.xml" />
+    <tool file="new_operations/merge.xml" />
+    <tool file="new_operations/concat.xml" />
+    <tool file="new_operations/basecoverage.xml" />
+    <tool file="new_operations/coverage.xml" />
+    <tool file="new_operations/complement.xml" />
+    <tool file="new_operations/cluster.xml" id="cluster" />
+    <tool file="new_operations/join.xml" />
+    <tool file="new_operations/get_flanks.xml" />
+    <tool file="new_operations/flanking_features.xml" />
+    <tool file="annotation_profiler/annotation_profiler.xml" />
+  </section>
+  <section name="Statistics" id="stats">
+    <tool file="stats/gsummary.xml" />
+    <tool file="filters/uniq.xml" /> 
+    <tool file="stats/cor.xml" /> 
+  </section>
+  <section name="Graph/Display Data" id="plots">
+    <tool file="plotting/histogram2.xml" />
+    <tool file="plotting/scatterplot.xml" />
+    <tool file="plotting/xy_plot.xml" />
+    <tool file="visualization/GMAJ.xml" />
+    <tool file="visualization/build_ucsc_custom_track.xml" />
+  </section>
+  <section name="Regional Variation" id="regVar">
+    <tool file="regVariation/windowSplitter.xml" />
+    <tool file="regVariation/featureCounter.xml" />
+    <tool file="regVariation/quality_filter.xml" />
+    <tool file="regVariation/maf_cpg_filter.xml" />
+    <tool file="regVariation/getIndels_2way.xml" />
+    <tool file="regVariation/getIndels_3way.xml" />
+    <tool file="regVariation/getIndelRates_3way.xml" />
+    <tool file="regVariation/substitutions.xml" />
+    <tool file="regVariation/substitution_rates.xml" />
+    <tool file="regVariation/microsats_alignment_level.xml" />
+    <tool file="regVariation/microsats_mutability.xml" />
+  </section>
+  <section name="Multiple regression" id="multReg">
+    <tool file="regVariation/linear_regression.xml" />
+    <tool file="regVariation/best_regression_subsets.xml" />
+    <tool file="regVariation/rcve.xml" />
+  </section>
+ <section name="Evolution: HyPhy" id="hyphy">
+    <tool file="hyphy/hyphy_branch_lengths_wrapper.xml" />
+    <tool file="hyphy/hyphy_nj_tree_wrapper.xml" />
+    <tool file="hyphy/hyphy_dnds_wrapper.xml" />
+ </section>
+ <section name="Metagenomic analyses" id="tax_manipulation">
+    <tool file="taxonomy/gi2taxonomy.xml" />
+    <tool file="taxonomy/t2t_report.xml" />
+    <tool file="taxonomy/t2ps_wrapper.xml" />
+    <tool file="taxonomy/find_diag_hits.xml" />
+    <tool file="taxonomy/lca.xml" />
+    <tool file="taxonomy/poisson2test.xml" />
+  </section>
+  <section name="Short Read Analysis" id="short_read_analysis">
+    <tool file="metag_tools/short_reads_figure_score.xml" />
+    <tool file="metag_tools/short_reads_trim_seq.xml" />
+    <tool file="metag_tools/megablast_wrapper.xml" />
+    <tool file="metag_tools/megablast_xml_parser.xml" /> 
+  </section>
+  <section name="EMBOSS" id="EMBOSSLite">
+    <tool file="emboss_5/emboss_antigenic.xml" />
+    <tool file="emboss_5/emboss_backtranseq.xml" />
+    <tool file="emboss_5/emboss_banana.xml" />
+    <tool file="emboss_5/emboss_biosed.xml" />
+    <tool file="emboss_5/emboss_btwisted.xml" />
+    <tool file="emboss_5/emboss_cai_custom.xml" />
+    <tool file="emboss_5/emboss_cai.xml" />
+    <tool file="emboss_5/emboss_chaos.xml" />
+    <tool file="emboss_5/emboss_charge.xml" />
+    <tool file="emboss_5/emboss_checktrans.xml" />
+    <tool file="emboss_5/emboss_chips.xml" />
+    <tool file="emboss_5/emboss_cirdna.xml" />
+    <tool file="emboss_5/emboss_codcmp.xml" />
+    <tool file="emboss_5/emboss_coderet.xml" /> 
+    <tool file="emboss_5/emboss_compseq.xml" />
+    <tool file="emboss_5/emboss_cpgplot.xml" /> 
+    <tool file="emboss_5/emboss_cpgreport.xml" />
+    <tool file="emboss_5/emboss_cusp.xml" />
+    <tool file="emboss_5/emboss_cutseq.xml" />
+    <tool file="emboss_5/emboss_dan.xml" /> 
+    <tool file="emboss_5/emboss_degapseq.xml" />
+    <tool file="emboss_5/emboss_descseq.xml" />
+    <tool file="emboss_5/emboss_diffseq.xml" />
+    <tool file="emboss_5/emboss_digest.xml" />
+    <tool file="emboss_5/emboss_dotmatcher.xml" />
+    <tool file="emboss_5/emboss_dotpath.xml" />
+    <tool file="emboss_5/emboss_dottup.xml" />
+    <tool file="emboss_5/emboss_dreg.xml" />
+    <tool file="emboss_5/emboss_einverted.xml" />
+    <tool file="emboss_5/emboss_epestfind.xml" />
+    <tool file="emboss_5/emboss_equicktandem.xml" />
+    <tool file="emboss_5/emboss_est2genome.xml" />
+    <tool file="emboss_5/emboss_etandem.xml" />
+    <tool file="emboss_5/emboss_extractfeat.xml" />
+    <tool file="emboss_5/emboss_extractseq.xml" />
+    <tool file="emboss_5/emboss_freak.xml" /> 
+    <tool file="emboss_5/emboss_fuzznuc.xml" />
+    <tool file="emboss_5/emboss_fuzzpro.xml" />
+    <tool file="emboss_5/emboss_fuzztran.xml" />
+    <tool file="emboss_5/emboss_garnier.xml" />
+    <tool file="emboss_5/emboss_geecee.xml" />
+    <tool file="emboss_5/emboss_getorf.xml" />
+    <tool file="emboss_5/emboss_helixturnhelix.xml" />
+    <tool file="emboss_5/emboss_hmoment.xml" />
+    <tool file="emboss_5/emboss_iep.xml" />
+    <tool file="emboss_5/emboss_infoseq.xml" />
+    <tool file="emboss_5/emboss_isochore.xml" />
+    <tool file="emboss_5/emboss_lindna.xml" />
+    <tool file="emboss_5/emboss_marscan.xml" />
+    <tool file="emboss_5/emboss_maskfeat.xml" />
+    <tool file="emboss_5/emboss_maskseq.xml" />
+    <tool file="emboss_5/emboss_matcher.xml" />
+    <tool file="emboss_5/emboss_megamerger.xml" />
+    <tool file="emboss_5/emboss_merger.xml" />
+    <tool file="emboss_5/emboss_msbar.xml" />
+    <tool file="emboss_5/emboss_needle.xml" />
+    <tool file="emboss_5/emboss_newcpgreport.xml" /> 
+    <tool file="emboss_5/emboss_newcpgseek.xml" />
+    <tool file="emboss_5/emboss_newseq.xml" />
+    <tool file="emboss_5/emboss_noreturn.xml" />
+    <tool file="emboss_5/emboss_notseq.xml" />
+    <tool file="emboss_5/emboss_nthseq.xml" />
+    <tool file="emboss_5/emboss_octanol.xml" />
+    <tool file="emboss_5/emboss_oddcomp.xml" />
+    <tool file="emboss_5/emboss_palindrome.xml" />
+    <tool file="emboss_5/emboss_pasteseq.xml" />
+    <tool file="emboss_5/emboss_patmatdb.xml" />
+    <tool file="emboss_5/emboss_pepcoil.xml" />
+    <tool file="emboss_5/emboss_pepinfo.xml" />
+    <tool file="emboss_5/emboss_pepnet.xml" />
+    <tool file="emboss_5/emboss_pepstats.xml" />
+    <tool file="emboss_5/emboss_pepwheel.xml" />
+    <tool file="emboss_5/emboss_pepwindow.xml" />
+    <tool file="emboss_5/emboss_pepwindowall.xml" />
+    <tool file="emboss_5/emboss_plotcon.xml" />
+    <tool file="emboss_5/emboss_plotorf.xml" />
+    <tool file="emboss_5/emboss_polydot.xml" />
+    <tool file="emboss_5/emboss_preg.xml" />
+    <tool file="emboss_5/emboss_prettyplot.xml" />
+    <tool file="emboss_5/emboss_prettyseq.xml" />
+    <tool file="emboss_5/emboss_primersearch.xml" />
+    <tool file="emboss_5/emboss_revseq.xml" />
+    <tool file="emboss_5/emboss_seqmatchall.xml" />
+    <tool file="emboss_5/emboss_seqret.xml" />
+    <tool file="emboss_5/emboss_showfeat.xml" /> 
+    <tool file="emboss_5/emboss_shuffleseq.xml" />
+    <tool file="emboss_5/emboss_sigcleave.xml" />
+    <tool file="emboss_5/emboss_sirna.xml" />
+    <tool file="emboss_5/emboss_sixpack.xml" />
+    <tool file="emboss_5/emboss_skipseq.xml" />
+    <tool file="emboss_5/emboss_splitter.xml" />
+    <tool file="emboss_5/emboss_supermatcher.xml" />
+    <tool file="emboss_5/emboss_syco.xml" />
+    <tool file="emboss_5/emboss_tcode.xml" />
+    <tool file="emboss_5/emboss_textsearch.xml" />
+    <tool file="emboss_5/emboss_tmap.xml" />
+    <tool file="emboss_5/emboss_tranalign.xml" />
+    <tool file="emboss_5/emboss_transeq.xml" />
+    <tool file="emboss_5/emboss_trimest.xml" />
+    <tool file="emboss_5/emboss_trimseq.xml" />
+    <tool file="emboss_5/emboss_twofeat.xml" />
+    <tool file="emboss_5/emboss_union.xml" />
+    <tool file="emboss_5/emboss_vectorstrip.xml" />
+    <tool file="emboss_5/emboss_water.xml" />
+    <tool file="emboss_5/emboss_wobble.xml" />
+    <tool file="emboss_5/emboss_wordcount.xml" />
+    <tool file="emboss_5/emboss_wordmatch.xml" /> 
+  </section>
+</toolbox>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/8877ef766447
changeset: 2680:8877ef766447
user:      Greg Von Kuster <greg(a)bx.psu.edu>
date:      Fri Sep 11 11:26:26 2009 -0400
description:
Fix for cleanup_datasets.py script.
1 file(s) affected in this change:
scripts/cleanup_datasets/cleanup_datasets.py
diffs (25 lines):
diff -r ed4cbaf23c88 -r 8877ef766447 scripts/cleanup_datasets/cleanup_datasets.py
--- a/scripts/cleanup_datasets/cleanup_datasets.py	Fri Sep 11 09:00:36 2009 -0400
+++ b/scripts/cleanup_datasets/cleanup_datasets.py	Fri Sep 11 11:26:26 2009 -0400
@@ -1,4 +1,8 @@
 #!/usr/bin/env python
+
+from galaxy import eggs
+import pkg_resources  
+pkg_resources.require( "SQLAlchemy >= 0.4" )
 
 import sys, os, time, ConfigParser, shutil
 from datetime import datetime, timedelta
@@ -9,12 +13,7 @@
 new_path.extend( sys.path[1:] ) # remove scripts/ from the path
 sys.path = new_path
 
-from galaxy import eggs
 import galaxy.model.mapping
-import pkg_resources
-        
-pkg_resources.require( "SQLAlchemy >= 0.4" )
-
 from galaxy.model.orm import and_, eagerload
 
 assert sys.version_info[:2] >= ( 2, 4 )
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    14 Sep '09
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/ed4cbaf23c88
changeset: 2679:ed4cbaf23c88
user:      Greg Von Kuster <greg(a)bx.psu.edu>
date:      Fri Sep 11 09:00:36 2009 -0400
description:
Eliminate buttons from shared history grid that were not meant to be committed.
1 file(s) affected in this change:
lib/galaxy/web/controllers/history.py
diffs (35 lines):
diff -r f0adb6152df9 -r ed4cbaf23c88 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py	Thu Sep 10 21:24:06 2009 -0400
+++ b/lib/galaxy/web/controllers/history.py	Fri Sep 11 09:00:36 2009 -0400
@@ -104,9 +104,7 @@
     ]
     operations = [
         grids.GridOperation( "Clone" ),
-        grids.GridOperation( "Unshare" ),
-        grids.GridOperation( "Enable import via link", condition=( lambda item: item.deleted ) ),
-        grids.GridOperation( "Disable import via link", condition=( lambda item: item.deleted ) )
+        grids.GridOperation( "Unshare" )
     ]
     standard_filters = []
     def build_initial_query( self, session ):
@@ -280,20 +278,6 @@
                     association.flush()
                 message = "Unshared %d shared histories" % len( ids )
                 status = 'done'
-            elif operation == "enable import via link":
-                if ids:
-                    histories = [ get_history( trans, id ) for id in ids ]
-                    for history in histories:
-                        if not history.importable:
-                            history.importable = True
-                            history.flush()
-            elif operation == "disable import via link":
-                if ids:
-                    histories = [ get_history( trans, id ) for id in ids ]
-                    for history in histories:
-                        if history.importable:
-                            history.importable = False
-                            history.flush()
         # Render the list view
         return self.shared_list_grid( trans, status=status, message=message, **kwargs )
     @web.expose
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    14 Sep '09
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/e7b899fb4462
changeset: 2681:e7b899fb4462
user:      James Taylor <james(a)jamestaylor.org>
date:      Fri Sep 11 12:48:33 2009 -0400
description:
Fix syntax error when running workflows. This is actually a regression in Mako, the multiline conditional in the elif was somehow causing it to improperly nest the if statements
2 file(s) affected in this change:
eggs.ini
templates/workflow/run.mako
diffs (34 lines):
diff -r 8877ef766447 -r e7b899fb4462 eggs.ini
--- a/eggs.ini	Fri Sep 11 11:26:26 2009 -0400
+++ b/eggs.ini	Fri Sep 11 12:48:33 2009 -0400
@@ -31,7 +31,7 @@
 elementtree = 1.2.6_20050316
 lrucache = 0.2
 ;lsprof - james
-Mako = 0.2.4
+Mako = 0.2.5
 MyghtyUtils = 0.52
 nose = 0.9.1
 NoseHTML = 0.2
@@ -79,7 +79,7 @@
 docutils = http://downloads.sourceforge.net/docutils/docutils-0.4.tar.gz
 elementtree = http://effbot.org/downloads/elementtree-1.2.6-20050316.tar.gz
 lrucache = http://evan.prodromou.name/lrucache/lrucache-0.2.tar.gz
-Mako = http://www.makotemplates.org/downloads/Mako-0.2.4.tar.gz
+Mako = http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz
 MyghtyUtils = http://cheeseshop.python.org/packages/source/M/MyghtyUtils/MyghtyUtils-0.52…
 nose = http://www.somethingaboutorange.com/mrl/projects/nose/nose-0.9.1.tar.gz
 NoseHTML = http://dist.g2.bx.psu.edu/nosehtml-0.2.tar.bz2
diff -r 8877ef766447 -r e7b899fb4462 templates/workflow/run.mako
--- a/templates/workflow/run.mako	Fri Sep 11 11:26:26 2009 -0400
+++ b/templates/workflow/run.mako	Fri Sep 11 12:48:33 2009 -0400
@@ -87,8 +87,7 @@
                     ${param.get_html_field( t, value, other_values ).get_html( str(step.id) + "|" + prefix )}
                     <input type="hidden" name="${step.id}|__force_update__${prefix}${param.name}" value="true" />
                 %endif
-            %elif isinstance( value, RuntimeValue ) or \
-                  ( str(step.id) + '|__runtime__' + prefix + param.name ) in incoming:
+            %elif isinstance( value, RuntimeValue ) or ( str(step.id) + '|__runtime__' + prefix + param.name ) in incoming:
                 ## On the first load we may see a RuntimeValue, so we write
                 ## an input field using the initial value for the param.
                 ## Subsequents posts will no longer have the runtime value
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    14 Sep '09
                    
                        details:   http://www.bx.psu.edu/hg/galaxy/rev/032478337b82
changeset: 2683:032478337b82
user:      jeremy goecks <jeremy.goecks(a)emory.edu>
date:      Fri Sep 11 14:57:02 2009 -0400
description:
(1) Unicode support for tagging and (2) added tagging_common mako file to support creation and standardization of tagging elements across all pages.
9 file(s) affected in this change:
lib/galaxy/web/controllers/history.py
lib/galaxy/web/controllers/tag.py
static/scripts/autocomplete_tagging.js
static/scripts/packed/autocomplete_tagging.js
templates/dataset/edit_attributes.mako
templates/history/grid.mako
templates/root/history.mako
templates/tagging_common.mako
tool_conf.xml.main
diffs (781 lines):
diff -r ed4cbaf23c88 -r 032478337b82 lib/galaxy/web/controllers/history.py
--- a/lib/galaxy/web/controllers/history.py	Fri Sep 11 09:00:36 2009 -0400
+++ b/lib/galaxy/web/controllers/history.py	Fri Sep 11 14:57:02 2009 -0400
@@ -38,6 +38,17 @@
             if item.users_shared_with or item.importable:
                 return dict( operation="sharing" )
             return None
+    class TagsColumn( grids.GridColumn ):
+        def __init__(self, col_name):
+            grids.GridColumn.__init__(self, col_name)
+            self.tag_elt_id_gen = 0
+
+        def get_value( self, trans, grid, history ):
+            self.tag_elt_id_gen += 1
+            return trans.fill_template( "/tagging_common.mako", trans=trans,
+                                        tagged_item=history,
+                                        elt_id="tagging-elt" + str(self.tag_elt_id_gen) )
+
     # Grid definition
     title = "Stored histories"
     model_class = model.History
@@ -48,6 +59,7 @@
                           link=( lambda item: iff( item.deleted, None, dict( operation="switch", id=item.id ) ) ),
                           attach_popup=True ),
         DatasetsByStateColumn( "Datasets (by state)", ncells=4 ),
+        #TagsColumn( "Tags" ),
         StatusColumn( "Status", attach_popup=False ),
         grids.GridColumn( "Created", key="create_time", format=time_ago ),
         grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
diff -r ed4cbaf23c88 -r 032478337b82 lib/galaxy/web/controllers/tag.py
--- a/lib/galaxy/web/controllers/tag.py	Fri Sep 11 09:00:36 2009 -0400
+++ b/lib/galaxy/web/controllers/tag.py	Fri Sep 11 14:57:02 2009 -0400
@@ -4,7 +4,6 @@
 
 from galaxy.model import History, HistoryTagAssociation, Dataset, DatasetTagAssociation, \
     HistoryDatasetAssociation, HistoryDatasetAssociationTagAssociation, Page, PageTagAssociation
-
 from galaxy.web.base.controller import *
 from galaxy.tags.tag_handler import *
 from sqlalchemy.sql.expression import func, and_
@@ -15,65 +14,68 @@
     def __init__(self, app):
         BaseController.__init__(self, app)
         
-        # Set up dict for mapping from short-hand to full item class.
-        self.shorthand_to_item_class_dict = dict()
-        self.shorthand_to_item_class_dict["history"] = History
-        self.shorthand_to_item_class_dict["hda"] = HistoryDatasetAssociation
+        # Keep a list of taggable classes.
+        self.taggable_classes = dict()
+        self.taggable_classes[History.__name__] = History
+        self.taggable_classes[HistoryDatasetAssociation.__name__] = HistoryDatasetAssociation
+        self.taggable_classes[Page.__name__] = Page
         
-        # Set up tag handler to recognize the following items: History, HistoryDatasetAssociation, ...
+        # Set up tag handler to recognize the following items: History, HistoryDatasetAssociation, Page, ...
         self.tag_handler = TagHandler()
         self.tag_handler.add_tag_assoc_class(History, HistoryTagAssociation)
         self.tag_handler.add_tag_assoc_class(HistoryDatasetAssociation, HistoryDatasetAssociationTagAssociation) 
-    
+        self.tag_handler.add_tag_assoc_class(Page, PageTagAssociation)
+        
     @web.expose
-    def add_tag_async( self, trans, id=None, item_type=None, new_tag=None ):
+    @web.require_login( "Add tag to an item." )
+    def add_tag_async( self, trans, id=None, item_class=None, new_tag=None ):
         """ Add tag to an item. """
-        item = self._get_item(trans, item_type, trans.security.decode_id(id))
+        item = self._get_item(trans, item_class, trans.security.decode_id(id))
         
         self._do_security_check(trans, item)
         
-        self.tag_handler.apply_item_tags(trans.sa_session, item, new_tag)
+        self.tag_handler.apply_item_tags( trans.sa_session, item, unicode(new_tag).encode('utf-8') )
         trans.sa_session.flush()
         
     @web.expose
-    def remove_tag_async( self, trans, id=None, item_type=None, tag_name=None ):
+    @web.require_login( "Remove tag from an item." )
+    def remove_tag_async( self, trans, id=None, item_class=None, tag_name=None ):
         """ Remove tag from an item. """
-        item = self._get_item(trans, item_type, trans.security.decode_id(id))
+        item = self._get_item(trans, item_class, trans.security.decode_id(id))
         
         self._do_security_check(trans, item)
         
-        self.tag_handler.remove_item_tag(item, tag_name)
+        self.tag_handler.remove_item_tag( item, unicode(tag_name).encode('utf-8') )
+        #print tag_name
+        #print unicode(tag_name)
         trans.sa_session.flush()
         
     # Retag an item. All previous tags are deleted and new tags are applied.
     @web.expose
-    def retag_async( self, trans, id=None, item_type=None, new_tags=None ):
+    @web.require_login( "Apply a new set of tags to an item; previous tags are deleted." )
+    def retag_async( self, trans, id=None, item_class=None, new_tags=None ):
         """ Apply a new set of tags to an item; previous tags are deleted. """  
-        item = self._get_item(trans, item_type, trans.security.decode_id(id))
+        item = self._get_item(trans, item_class, trans.security.decode_id(id))
         
         self._do_security_check(trans, item)
         
         tag_handler.delete_item_tags(item)
-        self.tag_handler.apply_item_tags(trans.sa_session, item, new_tag)
+        self.tag_handler.apply_item_tags( trans.sa_session, item, unicode(new_tags).encode('utf-8') )
         trans.sa_session.flush()
-        
-        tag_handler.delete_item_tags(history)
-        tag_handler.apply_item_tags(trans.sa_session, history, new_tags)
-        # Flush to complete changes.    
-        trans.sa_session.flush()
-        
+                
     @web.expose
     @web.require_login( "get autocomplete data for an item's tags" )
-    def tag_autocomplete_data(self, trans, id=None, item_type=None, q=None, limit=None, timestamp=None):
+    def tag_autocomplete_data(self, trans, id=None, item_class=None, q=None, limit=None, timestamp=None):
         """ Get autocomplete data for an item's tags. """
         
         #
         # Get item, do security check, and get autocomplete data.
         #
-        item = self._get_item(trans, item_type, trans.security.decode_id(id))
+        item = self._get_item(trans, item_class, trans.security.decode_id(id))
         
         self._do_security_check(trans, item)
         
+        q = unicode(q).encode('utf-8')
         if q.find(":") == -1:
             return self._get_tag_autocomplete_names(trans, item, q, limit, timestamp)
         else:
@@ -184,9 +186,9 @@
             # Use the user_id associated with the HDA's history.
             return History.table.c.user_id
     
-    def _get_item(self, trans, item_type, id):
+    def _get_item(self, trans, item_class_name, id):
         """ Get an item based on type and id. """
-        item_class = self.shorthand_to_item_class_dict[item_type]
+        item_class = self.taggable_classes[item_class_name]
         item = trans.sa_session.query(item_class).filter("id=" + str(id))[0]
         return item;
         
diff -r ed4cbaf23c88 -r 032478337b82 static/scripts/autocomplete_tagging.js
--- a/static/scripts/autocomplete_tagging.js	Fri Sep 11 09:00:36 2009 -0400
+++ b/static/scripts/autocomplete_tagging.js	Fri Sep 11 14:57:02 2009 -0400
@@ -187,13 +187,14 @@
       // Tag button is image's parent.
       var tag_button = $(this).parent();
       
-      // Get tag name.
+      // Get tag name, value.
       var tag_name_elt = tag_button.find(".tag-name").eq(0);
       var tag_str = tag_name_elt.text();
-      var tag_name = get_tag_name_and_value(tag_str)[0];
+      var tag_name_and_value = get_tag_name_and_value(tag_str);
+      var tag_name = tag_name_and_value[0];
+      var tag_value = tag_name_and_value[1];
 
-      // TODO: should remove succeed if tag is not already applied to
-      // history?
+      var prev_button = tag_button.prev();
       tag_button.remove();
 
       // Remove tag from local list for consistency.
@@ -209,12 +210,28 @@
 	    data: { tag_name: tag_name },
 	    error: function() 
 	    { 
-	      // Failed. 
-	      alert( "Remove tag failed" ); 
+	      // Failed. Roll back changes and show alert.
+	      settings.tags[tag_name] = tag_value;
+	      if (prev_button.hasClass("tag-button"))
+			prev_button.after(tag_button);
+	      else
+			tag_area.prepend(tag_button);
+	      var new_text = settings.get_toggle_link_text_fn(settings.tags);
+	      alert( "Remove tag failed" );
+	
+	      toggle_link.text(new_text);
+		
+	      // TODO: no idea why it's necessary to set this up again.
+	      delete_img.mouseenter( function ()
+	      {
+		      $(this).attr("src", settings.delete_tag_img_rollover);
+	      });
+	      delete_img.mouseleave( function ()
+	      {	
+              $(this).attr("src", settings.delete_tag_img);
+	      });
 	    },
-	    success: function() 
-	    {
-	    }
+	    success: function() {}
       });
 
       return true;
@@ -323,8 +340,9 @@
 		data: { new_tag: new_value },
 		error: function() 
 		{
-		  // Remove tag and show alert.
+		  // Failed. Roll back changes and show alert.
 		  new_tag_button.remove();
+		  delete settings.tags[tag_name_and_value[0]];
 		  var new_text = settings.get_toggle_link_text_fn(settings.tags);
 		  toggle_link.text(new_text);
 		  alert( "Add tag failed" );
diff -r ed4cbaf23c88 -r 032478337b82 static/scripts/packed/autocomplete_tagging.js
--- a/static/scripts/packed/autocomplete_tagging.js	Fri Sep 11 09:00:36 2009 -0400
+++ b/static/scripts/packed/autocomplete_tagging.js	Fri Sep 11 14:57:02 2009 -0400
@@ -1,1 +1,1 @@
-var ac_tag_area_id_gen=1;jQuery.fn.autocomplete_tagging=function(c){var e={get_toggle_link_text_fn:function(u){var w="";var v=o(u);if(v!=0){w=v+(v!=0?" Tags":" Tag")}else{w="Add tags"}return w},tag_click_fn:function(u){},input_size:20,in_form:false,tags:{},use_toggle_link:true,item_id:"",add_tag_img:"",add_tag_img_rollover:"",delete_tag_img:"",ajax_autocomplete_tag_url:"",ajax_retag_url:"",ajax_delete_tag_url:"",ajax_add_tag_url:""};var p=jQuery.extend(e,c);var k="tag-area-"+(ac_tag_area_id_gen)++;var m=$("<div></div>").attr("id",k).addClass("tag-area");this.append(m);var o=function(u){if(u.length){return u.length}var v=0;for(element in u){v++}return v};var b=function(){var u=p.get_toggle_link_text_fn(p.tags);var v=$("<a href='/history/tags'>"+u+"</a>").addClass("toggle-link");v.click(function(){var w=(m.css("display")=="none");var x;if(w){x=function(){var y=o(p.tags);if(y==0){m.click()}}}else{x=function(){m.blur()}}m.slideToggle("fast",x);return false});return v};var s=b();
 if(p.use_toggle_link){this.prepend(s)}var t=function(u){var v=new Array();for(key in u){v[v.length]=key+"-->"+u[key]}return"{"+v.join(",")+"}"};var a=function(v,u){return v+((u!=""&&u)?":"+u:"")};var h=function(u){return u.split(":")};var i=function(u){var v=$("<img src='"+p.add_tag_img+"' rollover='"+p.add_tag_img_rollover+"'/>").addClass("add-tag-button");v.click(function(){$(this).hide();m.click();return false});return v};var j=function(u){var v=$("<img src='"+p.delete_tag_img+"'/>").addClass("delete-tag-img");v.mouseenter(function(){$(this).attr("src",p.delete_tag_img_rollover)});v.mouseleave(function(){$(this).attr("src",p.delete_tag_img)});v.click(function(){var B=$(this).parent();var A=B.find(".tag-name").eq(0);var z=A.text();var C=h(z)[0];B.remove();delete p.tags[C];var y=p.get_toggle_link_text_fn(p.tags);s.text(y);$.ajax({url:p.ajax_delete_tag_url,data:{tag_name:C},error:function(){alert("Remove tag failed")},success:function(){}});return true});var w=$("<span>"+u+"
 </span>").addClass("tag-name");w.click(function(){p.tag_click_fn(u);return true});var x=$("<span></span>").addClass("tag-button");x.append(w);x.append(v);return x};var d=function(v){var u;if(p.in_form){u=$("<textarea id='history-tag-input' rows='1' cols='"+p.input_size+"' value='"+v+"'></textarea>")}else{u=$("<input id='history-tag-input' type='text' size='"+p.input_size+"' value='"+v+"'></input>")}u.keyup(function(D){if(D.keyCode==27){$(this).trigger("blur")}else{if((D.keyCode==13)||(D.keyCode==188)||(D.keyCode==32)){new_value=this.value;if(return_key_pressed_for_autocomplete==true){return_key_pressed_for_autocomplete=false;return false}if(new_value.indexOf(": ",new_value.length-2)!=-1){this.value=new_value.substring(0,new_value.length-1);return false}if((D.keyCode==188)||(D.keyCode==32)){new_value=new_value.substring(0,new_value.length-1)}new_value=new_value.replace(/^\s+|\s+$/g,"");if(new_value.length<3){return false}this.value="";var A=j(new_value);var z=m.children(".tag
 -button");if(z.length!=0){var E=z.slice(z.length-1);E.after(A)}else{m.prepend(A)}var y=new_value.split(":");p.tags[y[0]]=y[1];var B=p.get_toggle_link_text_fn(p.tags);s.text(B);var C=$(this);$.ajax({url:p.ajax_add_tag_url,data:{new_tag:new_value},error:function(){A.remove();var F=p.get_toggle_link_text_fn(p.tags);s.text(F);alert("Add tag failed")},success:function(){C.flushCache()}});return false}}});var w=function(A,z,y,C,B){tag_name_and_value=C.split(":");return(tag_name_and_value.length==1?tag_name_and_value[0]:tag_name_and_value[1])};var x={selectFirst:false,formatItem:w,autoFill:false,highlight:false};u.autocomplete(p.ajax_autocomplete_tag_url,x);u.addClass("tag-input");return u};for(tag_name in p.tags){var q=p.tags[tag_name];var l=a(tag_name,q);var g=j(l,s,p.tags);m.append(g)}var n=d("");var f=i(n);m.blur(function(u){r=o(p.tags);if(r!=0){f.show();n.hide();m.removeClass("active-tag-area")}else{}});m.append(f);m.append(n);n.hide();m.click(function(w){var v=$(this).hasClas
 s("active-tag-area");if($(w.target).hasClass("delete-tag-img")&&!v){return false}if($(w.target).hasClass("tag-name")&&!v){return false}$(this).addClass("active-tag-area");f.hide();n.show();n.focus();var u=function(y){var x=m.attr("id");if(($(y.target).attr("id")!=x)&&($(y.target).parents().filter(x).length==0)){m.blur();$(document).unbind("click",u)}};$(window).click(u);return false});if(p.use_toggle_link){m.hide()}else{var r=o(p.tags);if(r==0){f.hide();n.show()}}return this.addClass("tag-element")};
\ No newline at end of file
+var ac_tag_area_id_gen=1;jQuery.fn.autocomplete_tagging=function(c){var e={get_toggle_link_text_fn:function(u){var w="";var v=o(u);if(v!=0){w=v+(v!=0?" Tags":" Tag")}else{w="Add tags"}return w},tag_click_fn:function(u){},input_size:20,in_form:false,tags:{},use_toggle_link:true,item_id:"",add_tag_img:"",add_tag_img_rollover:"",delete_tag_img:"",ajax_autocomplete_tag_url:"",ajax_retag_url:"",ajax_delete_tag_url:"",ajax_add_tag_url:""};var p=jQuery.extend(e,c);var k="tag-area-"+(ac_tag_area_id_gen)++;var m=$("<div></div>").attr("id",k).addClass("tag-area");this.append(m);var o=function(u){if(u.length){return u.length}var v=0;for(element in u){v++}return v};var b=function(){var u=p.get_toggle_link_text_fn(p.tags);var v=$("<a href='/history/tags'>"+u+"</a>").addClass("toggle-link");v.click(function(){var w=(m.css("display")=="none");var x;if(w){x=function(){var y=o(p.tags);if(y==0){m.click()}}}else{x=function(){m.blur()}}m.slideToggle("fast",x);return false});return v};var s=b();
 if(p.use_toggle_link){this.prepend(s)}var t=function(u){var v=new Array();for(key in u){v[v.length]=key+"-->"+u[key]}return"{"+v.join(",")+"}"};var a=function(v,u){return v+((u!=""&&u)?":"+u:"")};var h=function(u){return u.split(":")};var i=function(u){var v=$("<img src='"+p.add_tag_img+"' rollover='"+p.add_tag_img_rollover+"'/>").addClass("add-tag-button");v.click(function(){$(this).hide();m.click();return false});return v};var j=function(u){var v=$("<img src='"+p.delete_tag_img+"'/>").addClass("delete-tag-img");v.mouseenter(function(){$(this).attr("src",p.delete_tag_img_rollover)});v.mouseleave(function(){$(this).attr("src",p.delete_tag_img)});v.click(function(){var D=$(this).parent();var C=D.find(".tag-name").eq(0);var B=C.text();var z=h(B);var F=z[0];var y=z[1];var E=D.prev();D.remove();delete p.tags[F];var A=p.get_toggle_link_text_fn(p.tags);s.text(A);$.ajax({url:p.ajax_delete_tag_url,data:{tag_name:F},error:function(){p.tags[F]=y;if(E.hasClass("tag-button")){E.after(D)
 }else{m.prepend(D)}var G=p.get_toggle_link_text_fn(p.tags);alert("Remove tag failed");s.text(G);v.mouseenter(function(){$(this).attr("src",p.delete_tag_img_rollover)});v.mouseleave(function(){$(this).attr("src",p.delete_tag_img)})},success:function(){}});return true});var w=$("<span>"+u+"</span>").addClass("tag-name");w.click(function(){p.tag_click_fn(u);return true});var x=$("<span></span>").addClass("tag-button");x.append(w);x.append(v);return x};var d=function(v){var u;if(p.in_form){u=$("<textarea id='history-tag-input' rows='1' cols='"+p.input_size+"' value='"+v+"'></textarea>")}else{u=$("<input id='history-tag-input' type='text' size='"+p.input_size+"' value='"+v+"'></input>")}u.keyup(function(D){if(D.keyCode==27){$(this).trigger("blur")}else{if((D.keyCode==13)||(D.keyCode==188)||(D.keyCode==32)){new_value=this.value;if(return_key_pressed_for_autocomplete==true){return_key_pressed_for_autocomplete=false;return false}if(new_value.indexOf(": ",new_value.length-2)!=-1){thi
 s.value=new_value.substring(0,new_value.length-1);return false}if((D.keyCode==188)||(D.keyCode==32)){new_value=new_value.substring(0,new_value.length-1)}new_value=new_value.replace(/^\s+|\s+$/g,"");if(new_value.length<3){return false}this.value="";var A=j(new_value);var z=m.children(".tag-button");if(z.length!=0){var E=z.slice(z.length-1);E.after(A)}else{m.prepend(A)}var y=new_value.split(":");p.tags[y[0]]=y[1];var B=p.get_toggle_link_text_fn(p.tags);s.text(B);var C=$(this);$.ajax({url:p.ajax_add_tag_url,data:{new_tag:new_value},error:function(){A.remove();delete p.tags[y[0]];var F=p.get_toggle_link_text_fn(p.tags);s.text(F);alert("Add tag failed")},success:function(){C.flushCache()}});return false}}});var w=function(A,z,y,C,B){tag_name_and_value=C.split(":");return(tag_name_and_value.length==1?tag_name_and_value[0]:tag_name_and_value[1])};var x={selectFirst:false,formatItem:w,autoFill:false,highlight:false};u.autocomplete(p.ajax_autocomplete_tag_url,x);u.addClass("tag-input
 ");return u};for(tag_name in p.tags){var q=p.tags[tag_name];var l=a(tag_name,q);var g=j(l,s,p.tags);m.append(g)}var n=d("");var f=i(n);m.blur(function(u){r=o(p.tags);if(r!=0){f.show();n.hide();m.removeClass("active-tag-area")}else{}});m.append(f);m.append(n);n.hide();m.click(function(w){var v=$(this).hasClass("active-tag-area");if($(w.target).hasClass("delete-tag-img")&&!v){return false}if($(w.target).hasClass("tag-name")&&!v){return false}$(this).addClass("active-tag-area");f.hide();n.show();n.focus();var u=function(y){var x=m.attr("id");if(($(y.target).attr("id")!=x)&&($(y.target).parents().filter(x).length==0)){m.blur();$(document).unbind("click",u)}};$(window).click(u);return false});if(p.use_toggle_link){m.hide()}else{var r=o(p.tags);if(r==0){f.hide();n.show()}}return this.addClass("tag-element")};
\ No newline at end of file
diff -r ed4cbaf23c88 -r 032478337b82 templates/dataset/edit_attributes.mako
--- a/templates/dataset/edit_attributes.mako	Fri Sep 11 09:00:36 2009 -0400
+++ b/templates/dataset/edit_attributes.mako	Fri Sep 11 14:57:02 2009 -0400
@@ -9,43 +9,8 @@
 <% user, user_roles = trans.get_user_and_roles() %>
 
 <%def name="javascripts()">
-    ## <!--[if lt IE 7]>
-    ## <script type='text/javascript' src="/static/scripts/IE7.js"> </script>
-    ## <![endif]-->
-    ${h.js( "jquery", "galaxy.base", "jquery.autocomplete", "autocomplete_tagging" )}
-    <script type="text/javascript">
-    $( document ).ready( function() {
-        // Set up autocomplete tagger.
-<%
-    ## Build string of tag name, values.
-    tag_names_and_values = list()
-    for tag in data.tags:
-        tag_name = tag.user_tname
-        tag_value = ""
-        if tag.value is not None:
-            tag_value = tag.user_value
-        tag_names_and_values.append("\"" + tag_name + "\" : \"" + tag_value + "\"") 
-%>
-        var options = {
-            tags : {${", ".join(tag_names_and_values)}},
-            tag_click_fn: function(tag) { /* Do nothing. */ },
-            use_toggle_link: false,
-            input_size: 30,
-            in_form: true,
-            <% encoded_data_id = trans.security.encode_id(data.id) %>
-            ajax_autocomplete_tag_url: "${h.url_for( controller='tag', action='tag_autocomplete_data', id=encoded_data_id, item_type="hda" )}",
-            ajax_add_tag_url: "${h.url_for( controller='tag', action='add_tag_async', id=encoded_data_id, item_type="hda" )}",
-            ajax_delete_tag_url: "${h.url_for( controller='tag', action='remove_tag_async', id=encoded_data_id, item_type="hda" )}",
-            delete_tag_img: "${h.url_for('/static/images/delete_tag_icon_gray.png')}",
-            delete_tag_img_rollover: "${h.url_for('/static/images/delete_tag_icon_white.png')}",
-            add_tag_img: "${h.url_for('/static/images/add_icon.png')}",
-            add_tag_img_rollover: "${h.url_for('/static/images/add_icon_dark.png')}",
-        };
-% if trans.get_user() is not None:
-    $("#dataset-tag-area").autocomplete_tagging(options);
-% endif
-});
-    </script>
+    ${parent.javascripts()}
+    ${h.js( "jquery.autocomplete", "autocomplete_tagging" )}
 </%def>
 
 <%def name="datatype( dataset, datatypes )">
@@ -84,16 +49,18 @@
                 <div style="clear: both"></div>
             </div>
             %if trans.get_user() is not None:
-             <div class="form-row">
-                 <label>
-                     Tags:
-                 </label>
-                 <div id="dataset-tag-area" 
+			<%namespace file="../tagging_common.mako" import="render_tagging_element" />
+            <div class="form-row">
+                <label>
+                    Tags:
+                </label>
+                <div id="dataset-tag-area" 
                       style="float: left; margin-left: 1px; width: 295px; margin-right: 10px; border-style: inset; border-color: #ddd; border-width: 1px">
-                 </div>
-                 <div style="clear: both"></div>
-             </div>
-             %endif
+                </div>
+                <div style="clear: both"></div>
+            </div>
+			${render_tagging_element(data, "dataset-tag-area", use_toggle_link="false", in_form="true", input_size="30")}
+            %endif
             %for name, spec in data.metadata.spec.items():
                 %if spec.visible:
                     <div class="form-row">
diff -r ed4cbaf23c88 -r 032478337b82 templates/history/grid.mako
--- a/templates/history/grid.mako	Fri Sep 11 09:00:36 2009 -0400
+++ b/templates/history/grid.mako	Fri Sep 11 14:57:02 2009 -0400
@@ -10,6 +10,7 @@
 
 <%def name="javascripts()">
     ${parent.javascripts()}
+	${h.js("jquery.autocomplete", "autocomplete_tagging" )}
     <script type="text/javascript">        
         ## TODO: generalize and move into galaxy.base.js
         $(document).ready(function() {
@@ -58,7 +59,7 @@
 </%def>
 
 <%def name="stylesheets()">
-    <link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
+    ${h.css( "base", "autocomplete_tagging" )}
     <style>
         ## Not generic to all grids -- move to base?
         .count-box {
diff -r ed4cbaf23c88 -r 032478337b82 templates/root/history.mako
--- a/templates/root/history.mako	Fri Sep 11 09:00:36 2009 -0400
+++ b/templates/root/history.mako	Fri Sep 11 14:57:02 2009 -0400
@@ -77,83 +77,6 @@
         <% updateable = [data for data in reversed( datasets ) if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]] %>
         ${ ",".join( map(lambda data: "\"%s\" : \"%s\"" % (data.id, data.state), updateable) ) }
     });
-    
-    // Set up autocomplete tagger.
-<%
-    ## Build string of tag name, values.
-    tag_names_and_values = list()
-    for tag in history.tags:
-        tag_name = tag.user_tname
-        tag_value = ""
-        if tag.value is not None:
-            tag_value = tag.user_value
-        tag_names_and_values.append("\"" + tag_name + "\" : \"" + tag_value + "\"") 
-%>
-    // Returns the number of keys (elements) in an array/dictionary.
-    var array_length = function(an_array)
-    {
-        if (an_array.length)
-        return an_array.length;
-
-        var count = 0;
-        for (element in an_array)
-        count++;
-        return count;
-    };
-
-    // Function get text to display on the toggle link.
-    var get_toggle_link_text = function(tags) 
-    {
-        var text = "";
-        var num_tags = array_length(tags);
-        if (num_tags != 0) {
-            text = num_tags + (num_tags != 1 ? " Tags" : " Tag");
-        /*
-        // Show first N tags; hide the rest.
-        var max_to_show = 1;
-
-        // Build tag string.
-        var tag_strs = new Array();
-        var count = 0;
-        for (tag_name in tags)
-          {
-            tag_value = tags[tag_name];
-            tag_strs[tag_strs.length] = build_tag_str(tag_name, tag_value);
-            if (++count == max_to_show)
-              break;
-          }
-        tag_str = tag_strs.join(", ");
-
-        // Finalize text.
-        var num_tags_hiding = num_tags - max_to_show;
-        text = "Tags: " + tag_str + 
-          (num_tags_hiding != 0 ? " and " + num_tags_hiding + " more" : "");
-        */
-        } else {
-            // No tags.
-            text = "Add tags to this history";
-        }
-        return text;
-    };
-    
-    var options = {
-        tags : {${", ".join(tag_names_and_values)}},
-        get_toggle_link_text_fn: get_toggle_link_text,
-        input_size: 15,
-        tag_click_fn: function(tag) { /* Do nothing. */ },
-        <% encoded_history_id = trans.security.encode_id(history.id) %>
-        ajax_autocomplete_tag_url: "${h.url_for( controller='tag', action='tag_autocomplete_data', id=encoded_history_id, item_type="history" )}",
-        ajax_add_tag_url: "${h.url_for( controller='tag', action='add_tag_async', id=encoded_history_id, item_type="history" )}",
-        ajax_delete_tag_url: "${h.url_for( controller='tag', action='remove_tag_async', id=encoded_history_id, item_type="history" )}",
-        delete_tag_img: "${h.url_for('/static/images/delete_tag_icon_gray.png')}",
-        delete_tag_img_rollover: "${h.url_for('/static/images/delete_tag_icon_white.png')}",
-        add_tag_img: "${h.url_for('/static/images/add_icon.png')}",
-        add_tag_img_rollover: "${h.url_for('/static/images/add_icon_dark.png')}",
-    };
-% if trans.get_user() is not None:
-    $("#history-tag-area").autocomplete_tagging(options);
-% endif
-
 });
 // Functionized so AJAX'd datasets can call them
 function initShowHide() {
@@ -361,7 +284,13 @@
 <div id="history-tag-area" style="margin-bottom: 1em">
 </div>
 
+<%namespace file="../tagging_common.mako" import="render_tagging_element" />
 <%namespace file="history_common.mako" import="render_dataset" />
+
+%if trans.get_user() is not None:
+    <div id='history-tag-area' class="tag-element"></div>
+    ${render_tagging_element(history, "history-tag-area")}
+%endif
 
 %if not datasets:
 
diff -r ed4cbaf23c88 -r 032478337b82 templates/tagging_common.mako
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/tagging_common.mako	Fri Sep 11 14:57:02 2009 -0400
@@ -0,0 +1,92 @@
+## Render the tags 'tags' as an autocomplete element.
+<%def name="render_tagging_element(tagged_item, elt_id, use_toggle_link='true', in_form='false', input_size='15')">
+    <script type="text/javascript">
+        
+        //
+        // Set up autocomplete tagger.
+        //
+        <%
+            ## Build string of tag name, values.
+            tag_names_and_values = list()
+            for tag in tagged_item.tags:
+                tag_name = tag.user_tname
+                tag_value = ""
+                if tag.value is not None:
+                    tag_value = tag.user_value
+                tag_names_and_values.append( ("\"" + tag_name + "\" : \"" + tag_value + "\"") )
+        %>
+        //    
+        // Returns the number of keys (elements) in an array/dictionary.
+        //
+        var array_length = function(an_array)
+        {
+            if (an_array.length)
+                return an_array.length;
+    
+            var count = 0;
+            for (element in an_array)   
+                count++;
+            return count;
+        };
+    
+        //
+        // Function get text to display on the toggle link.
+        //
+        var get_toggle_link_text = function(tags)
+        {
+            var text = "";
+            var num_tags = array_length(tags);
+            if (num_tags != 0)
+              {
+                text = num_tags + (num_tags != 1 ? " Tags" : " Tag");
+                /*
+                // Show first N tags; hide the rest.
+                var max_to_show = 1;
+    
+                // Build tag string.
+                var tag_strs = new Array();
+                var count = 0;
+                for (tag_name in tags)
+                  {
+                    tag_value = tags[tag_name];
+                    tag_strs[tag_strs.length] = build_tag_str(tag_name, tag_value);
+                    if (++count == max_to_show)
+                      break;
+                  }
+                tag_str = tag_strs.join(", ");
+            
+                // Finalize text.
+                var num_tags_hiding = num_tags - max_to_show;
+                text = "Tags: " + tag_str + 
+                  (num_tags_hiding != 0 ? " and " + num_tags_hiding + " more" : "");
+                */
+              }
+            else
+              {
+                // No tags.
+                text = "Add tags to history";
+              }
+            return text;
+        };
+        
+        var options =
+        {
+          tags : {${unicode(", ".join(tag_names_and_values), 'utf-8')}},
+          get_toggle_link_text_fn: get_toggle_link_text,
+          tag_click_fn: function(tag) { /* Do nothing. */ },
+          <% tagged_item_id = trans.security.encode_id(tagged_item.id) %>
+          ajax_autocomplete_tag_url: "${h.url_for( controller='tag', action='tag_autocomplete_data', id=tagged_item_id, item_class=tagged_item.__class__.__name__ )}",
+          ajax_add_tag_url: "${h.url_for( controller='tag', action='add_tag_async', id=tagged_item_id, item_class=tagged_item.__class__.__name__ )}",
+          ajax_delete_tag_url: "${h.url_for( controller='tag', action='remove_tag_async', id=tagged_item_id, item_class=tagged_item.__class__.__name__ )}",
+          delete_tag_img: "${h.url_for('/static/images/delete_tag_icon_gray.png')}",
+          delete_tag_img_rollover: "${h.url_for('/static/images/delete_tag_icon_white.png')}",
+          add_tag_img: "${h.url_for('/static/images/add_icon.png')}",
+          add_tag_img_rollover: "${h.url_for('/static/images/add_icon_dark.png')}",
+          input_size: ${input_size},
+          in_form: ${in_form},
+          use_toggle_link: ${use_toggle_link}
+         };
+         
+        $("#${elt_id}").autocomplete_tagging(options)
+    </script>
+</%def>
\ No newline at end of file
diff -r ed4cbaf23c88 -r 032478337b82 tool_conf.xml.main
--- a/tool_conf.xml.main	Fri Sep 11 09:00:36 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-<?xml version="1.0"?>
-<toolbox>
-  <section name="Get Data" id="getext">
-    <tool file="data_source/upload.xml"/>
-    <tool file="data_source/ucsc_tablebrowser.xml" />
-    <tool file="data_source/ucsc_tablebrowser_archaea.xml" />
-    <tool file="data_source/microbial_import.xml" />
-    <tool file="data_source/biomart.xml" />
-    <tool file="data_source/gramene_mart.xml" />
-    <tool file="data_source/flymine.xml" />
-    <tool file="data_source/encode_db.xml" />
-    <tool file="data_source/epigraph_import.xml" />
-  </section>
-  <section name="Send Data" id="send">
-    <tool file="data_destination/epigraph.xml" />
-  </section>
-  <section name="ENCODE Tools" id="EncodeTools">
-    <tool file="encode/gencode_partition.xml" />
-    <tool file="encode/random_intervals.xml" />
-  </section>
-  <section name="Lift-Over" id="liftOver">
-    <tool file="extract/liftOver_wrapper.xml" />
-  </section>
-  <section name="Text Manipulation" id="textutil">
-    <tool file="filters/fixedValueColumn.xml" />
-    <tool file="stats/column_maker.xml" />
-    <tool file="filters/catWrapper.xml" />
-    <tool file="filters/condense_characters.xml" />
-    <tool file="filters/convert_characters.xml" />
-    <tool file="filters/CreateInterval.xml" />
-    <tool file="filters/cutWrapper.xml" />
-    <tool file="filters/changeCase.xml" />
-    <tool file="filters/pasteWrapper.xml" />
-    <tool file="filters/remove_beginning.xml" />
-    <tool file="filters/headWrapper.xml" />
-    <tool file="filters/tailWrapper.xml" />
-  </section>
-  <section name="Convert Formats" id="convert">
-    <tool file="filters/bed2gff.xml" />
-    <tool file="fasta_tools/fasta_to_tabular.xml" />
-    <tool file="filters/gff2bed.xml" />
-    <tool file="maf/maf_to_bed.xml" />
-    <tool file="maf/maf_to_fasta.xml" />
-    <tool file="fasta_tools/tabular_to_fasta.xml" />
-  </section>
-  <section name="FASTA manipulation" id="fasta_manipulation">
-    <tool file="fasta_tools/fasta_compute_length.xml" />
-    <tool file="fasta_tools/fasta_filter_by_length.xml" />
-    <tool file="fasta_tools/fasta_concatenate_by_species.xml" />
-    <tool file="fasta_tools/fasta_to_tabular.xml" />
-    <tool file="fasta_tools/tabular_to_fasta.xml" />
-  </section>
-  <section name="Filter and Sort" id="filter">
-    <tool file="stats/filtering.xml" />
-    <tool file="filters/sorter.xml" />
-    <tool file="filters/grep.xml" />
-  </section>
-  <section name="Join, Subtract and Group" id="group">
-    <tool file="filters/joiner.xml" />
-    <tool file="filters/compare.xml"/>
-    <tool file="new_operations/subtract_query.xml"/>
-    <tool file="stats/grouping.xml" />   
-  </section>
-  <section name="Extract Features" id="features">
-    <tool file="filters/ucsc_gene_bed_to_exon_bed.xml" />
-    <tool file="extract/extract_GFF_Features.xml" />
-  </section>
-  <section name="Fetch Sequences" id="fetchSeq">
-    <tool file="extract/extract_genomic_dna.xml" />
-  </section>
-  <section name="Fetch Alignments" id="fetchAlign">
-    <tool file="maf/interval2maf_pairwise.xml" />
-    <tool file="maf/interval2maf.xml" />
-    <tool file="maf/interval_maf_to_merged_fasta.xml" />
-    <tool file="maf/genebed_maf_to_fasta.xml"/>
-    <tool file="maf/maf_stats.xml"/>
-    <tool file="maf/maf_thread_for_species.xml"/>
-    <tool file="maf/maf_limit_to_species.xml"/>
-    <tool file="maf/maf_limit_size.xml"/>
-    <tool file="maf/maf_by_block_number.xml"/>
-    <tool file="maf/maf_filter.xml"/>
-    <!--    
-    <tool file="maf/maf_reverse_complement.xml"/>
-    -->
-  </section>
-  <section name="Get Genomic Scores" id="scores">
-    <tool file="stats/wiggle_to_simple.xml" />
-    <tool file="stats/aggregate_binned_scores_in_intervals.xml" />
-    <tool file="extract/phastOdds/phastOdds_tool.xml" />
-  </section>
-  <section name="Operate on Genomic Intervals" id="bxops">
-  	<tool file="new_operations/intersect.xml" />  
-    <tool file="new_operations/subtract.xml" />
-    <tool file="new_operations/merge.xml" />
-    <tool file="new_operations/concat.xml" />
-    <tool file="new_operations/basecoverage.xml" />
-    <tool file="new_operations/coverage.xml" />
-    <tool file="new_operations/complement.xml" />
-    <tool file="new_operations/cluster.xml" id="cluster" />
-    <tool file="new_operations/join.xml" />
-    <tool file="new_operations/get_flanks.xml" />
-    <tool file="new_operations/flanking_features.xml" />
-    <tool file="annotation_profiler/annotation_profiler.xml" />
-  </section>
-  <section name="Statistics" id="stats">
-    <tool file="stats/gsummary.xml" />
-    <tool file="filters/uniq.xml" /> 
-    <tool file="stats/cor.xml" /> 
-  </section>
-  <section name="Graph/Display Data" id="plots">
-    <tool file="plotting/histogram2.xml" />
-    <tool file="plotting/scatterplot.xml" />
-    <tool file="plotting/xy_plot.xml" />
-    <tool file="visualization/GMAJ.xml" />
-    <tool file="visualization/build_ucsc_custom_track.xml" />
-  </section>
-  <section name="Regional Variation" id="regVar">
-    <tool file="regVariation/windowSplitter.xml" />
-    <tool file="regVariation/featureCounter.xml" />
-    <tool file="regVariation/quality_filter.xml" />
-    <tool file="regVariation/maf_cpg_filter.xml" />
-    <tool file="regVariation/getIndels_2way.xml" />
-    <tool file="regVariation/getIndels_3way.xml" />
-    <tool file="regVariation/getIndelRates_3way.xml" />
-    <tool file="regVariation/substitutions.xml" />
-    <tool file="regVariation/substitution_rates.xml" />
-    <tool file="regVariation/microsats_alignment_level.xml" />
-    <tool file="regVariation/microsats_mutability.xml" />
-  </section>
-  <section name="Multiple regression" id="multReg">
-    <tool file="regVariation/linear_regression.xml" />
-    <tool file="regVariation/best_regression_subsets.xml" />
-    <tool file="regVariation/rcve.xml" />
-  </section>
- <section name="Evolution: HyPhy" id="hyphy">
-    <tool file="hyphy/hyphy_branch_lengths_wrapper.xml" />
-    <tool file="hyphy/hyphy_nj_tree_wrapper.xml" />
-    <tool file="hyphy/hyphy_dnds_wrapper.xml" />
- </section>
- <section name="Metagenomic analyses" id="tax_manipulation">
-    <tool file="taxonomy/gi2taxonomy.xml" />
-    <tool file="taxonomy/t2t_report.xml" />
-    <tool file="taxonomy/t2ps_wrapper.xml" />
-    <tool file="taxonomy/find_diag_hits.xml" />
-    <tool file="taxonomy/lca.xml" />
-    <tool file="taxonomy/poisson2test.xml" />
-  </section>
-  <section name="Short Read Analysis" id="short_read_analysis">
-    <tool file="metag_tools/short_reads_figure_score.xml" />
-    <tool file="metag_tools/short_reads_trim_seq.xml" />
-    <tool file="metag_tools/megablast_wrapper.xml" />
-    <tool file="metag_tools/megablast_xml_parser.xml" /> 
-  </section>
-  <section name="EMBOSS" id="EMBOSSLite">
-    <tool file="emboss_5/emboss_antigenic.xml" />
-    <tool file="emboss_5/emboss_backtranseq.xml" />
-    <tool file="emboss_5/emboss_banana.xml" />
-    <tool file="emboss_5/emboss_biosed.xml" />
-    <tool file="emboss_5/emboss_btwisted.xml" />
-    <tool file="emboss_5/emboss_cai_custom.xml" />
-    <tool file="emboss_5/emboss_cai.xml" />
-    <tool file="emboss_5/emboss_chaos.xml" />
-    <tool file="emboss_5/emboss_charge.xml" />
-    <tool file="emboss_5/emboss_checktrans.xml" />
-    <tool file="emboss_5/emboss_chips.xml" />
-    <tool file="emboss_5/emboss_cirdna.xml" />
-    <tool file="emboss_5/emboss_codcmp.xml" />
-    <tool file="emboss_5/emboss_coderet.xml" /> 
-    <tool file="emboss_5/emboss_compseq.xml" />
-    <tool file="emboss_5/emboss_cpgplot.xml" /> 
-    <tool file="emboss_5/emboss_cpgreport.xml" />
-    <tool file="emboss_5/emboss_cusp.xml" />
-    <tool file="emboss_5/emboss_cutseq.xml" />
-    <tool file="emboss_5/emboss_dan.xml" /> 
-    <tool file="emboss_5/emboss_degapseq.xml" />
-    <tool file="emboss_5/emboss_descseq.xml" />
-    <tool file="emboss_5/emboss_diffseq.xml" />
-    <tool file="emboss_5/emboss_digest.xml" />
-    <tool file="emboss_5/emboss_dotmatcher.xml" />
-    <tool file="emboss_5/emboss_dotpath.xml" />
-    <tool file="emboss_5/emboss_dottup.xml" />
-    <tool file="emboss_5/emboss_dreg.xml" />
-    <tool file="emboss_5/emboss_einverted.xml" />
-    <tool file="emboss_5/emboss_epestfind.xml" />
-    <tool file="emboss_5/emboss_equicktandem.xml" />
-    <tool file="emboss_5/emboss_est2genome.xml" />
-    <tool file="emboss_5/emboss_etandem.xml" />
-    <tool file="emboss_5/emboss_extractfeat.xml" />
-    <tool file="emboss_5/emboss_extractseq.xml" />
-    <tool file="emboss_5/emboss_freak.xml" /> 
-    <tool file="emboss_5/emboss_fuzznuc.xml" />
-    <tool file="emboss_5/emboss_fuzzpro.xml" />
-    <tool file="emboss_5/emboss_fuzztran.xml" />
-    <tool file="emboss_5/emboss_garnier.xml" />
-    <tool file="emboss_5/emboss_geecee.xml" />
-    <tool file="emboss_5/emboss_getorf.xml" />
-    <tool file="emboss_5/emboss_helixturnhelix.xml" />
-    <tool file="emboss_5/emboss_hmoment.xml" />
-    <tool file="emboss_5/emboss_iep.xml" />
-    <tool file="emboss_5/emboss_infoseq.xml" />
-    <tool file="emboss_5/emboss_isochore.xml" />
-    <tool file="emboss_5/emboss_lindna.xml" />
-    <tool file="emboss_5/emboss_marscan.xml" />
-    <tool file="emboss_5/emboss_maskfeat.xml" />
-    <tool file="emboss_5/emboss_maskseq.xml" />
-    <tool file="emboss_5/emboss_matcher.xml" />
-    <tool file="emboss_5/emboss_megamerger.xml" />
-    <tool file="emboss_5/emboss_merger.xml" />
-    <tool file="emboss_5/emboss_msbar.xml" />
-    <tool file="emboss_5/emboss_needle.xml" />
-    <tool file="emboss_5/emboss_newcpgreport.xml" /> 
-    <tool file="emboss_5/emboss_newcpgseek.xml" />
-    <tool file="emboss_5/emboss_newseq.xml" />
-    <tool file="emboss_5/emboss_noreturn.xml" />
-    <tool file="emboss_5/emboss_notseq.xml" />
-    <tool file="emboss_5/emboss_nthseq.xml" />
-    <tool file="emboss_5/emboss_octanol.xml" />
-    <tool file="emboss_5/emboss_oddcomp.xml" />
-    <tool file="emboss_5/emboss_palindrome.xml" />
-    <tool file="emboss_5/emboss_pasteseq.xml" />
-    <tool file="emboss_5/emboss_patmatdb.xml" />
-    <tool file="emboss_5/emboss_pepcoil.xml" />
-    <tool file="emboss_5/emboss_pepinfo.xml" />
-    <tool file="emboss_5/emboss_pepnet.xml" />
-    <tool file="emboss_5/emboss_pepstats.xml" />
-    <tool file="emboss_5/emboss_pepwheel.xml" />
-    <tool file="emboss_5/emboss_pepwindow.xml" />
-    <tool file="emboss_5/emboss_pepwindowall.xml" />
-    <tool file="emboss_5/emboss_plotcon.xml" />
-    <tool file="emboss_5/emboss_plotorf.xml" />
-    <tool file="emboss_5/emboss_polydot.xml" />
-    <tool file="emboss_5/emboss_preg.xml" />
-    <tool file="emboss_5/emboss_prettyplot.xml" />
-    <tool file="emboss_5/emboss_prettyseq.xml" />
-    <tool file="emboss_5/emboss_primersearch.xml" />
-    <tool file="emboss_5/emboss_revseq.xml" />
-    <tool file="emboss_5/emboss_seqmatchall.xml" />
-    <tool file="emboss_5/emboss_seqret.xml" />
-    <tool file="emboss_5/emboss_showfeat.xml" /> 
-    <tool file="emboss_5/emboss_shuffleseq.xml" />
-    <tool file="emboss_5/emboss_sigcleave.xml" />
-    <tool file="emboss_5/emboss_sirna.xml" />
-    <tool file="emboss_5/emboss_sixpack.xml" />
-    <tool file="emboss_5/emboss_skipseq.xml" />
-    <tool file="emboss_5/emboss_splitter.xml" />
-    <tool file="emboss_5/emboss_supermatcher.xml" />
-    <tool file="emboss_5/emboss_syco.xml" />
-    <tool file="emboss_5/emboss_tcode.xml" />
-    <tool file="emboss_5/emboss_textsearch.xml" />
-    <tool file="emboss_5/emboss_tmap.xml" />
-    <tool file="emboss_5/emboss_tranalign.xml" />
-    <tool file="emboss_5/emboss_transeq.xml" />
-    <tool file="emboss_5/emboss_trimest.xml" />
-    <tool file="emboss_5/emboss_trimseq.xml" />
-    <tool file="emboss_5/emboss_twofeat.xml" />
-    <tool file="emboss_5/emboss_union.xml" />
-    <tool file="emboss_5/emboss_vectorstrip.xml" />
-    <tool file="emboss_5/emboss_water.xml" />
-    <tool file="emboss_5/emboss_wobble.xml" />
-    <tool file="emboss_5/emboss_wordcount.xml" />
-    <tool file="emboss_5/emboss_wordmatch.xml" /> 
-  </section>
-</toolbox>
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0