Index: /trunk/grails-app/controllers/AssetDetailedController.groovy
===================================================================
--- /trunk/grails-app/controllers/AssetDetailedController.groovy	(revision 270)
+++ /trunk/grails-app/controllers/AssetDetailedController.groovy	(revision 271)
@@ -1,12 +1,51 @@
 import org.codehaus.groovy.grails.plugins.springsecurity.Secured
+import org.codehaus.groovy.grails.commons.ConfigurationHolder
 
 class AssetDetailedController extends BaseController {
 
+    def csvService
     def filterService
+    def exportService
 
     def index = { redirect(action:search,params:params) }
 
     // the delete, save and update actions only accept POST requests
-    static allowedMethods = [delete:'POST', save:'POST', update:'POST']
+    static allowedMethods = [delete:'POST', save:'POST', update:'POST', saveCopy:'POST']
+
+    def importAssetTree = {
+    }
+
+    def importAssetTreeSave = {
+        def result = csvService.importAssetTree(request)
+
+        if(!result.error)
+            flash.message = g.message(code: "asset.tree.import.success")
+        else
+            flash.warning = g.message(code: result.error.code, args: result.error.args)
+
+        redirect(action: importAssetTree)
+    }
+
+    /**
+    * Export a csv template.
+    * NOTE: IE has a 'validating' bug in dev mode that causes the export to take a long time!
+    * This does not appear to be a problem once deployed to Tomcat.
+    */
+    def exportAssetTreeTemplate = {
+        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
+        response.setHeader("Content-disposition", "attachment; filename=AssetTreeTemplate.csv")
+        def s = csvService.buildAssetTreeTemplate()
+        render s
+    }
+
+    def exportAssetTree = {
+
+        def assetList = Asset.list()
+
+        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
+        response.setHeader("Content-disposition", "attachment; filename=AssetTree.csv")
+        def s = csvService.buildAssetTree(assetList)
+        render s
+    }
 
     def list = {
@@ -16,16 +55,100 @@
 
     def search = {
-        params.max = Math.min( params.max ? params.max.toInteger() : 10,  100)
+
+        if(session.taskSearchParamsMax)
+            params.max = session.taskSearchParamsMax
+
+        params.max = Math.min( params.max ? params.max.toInteger() : 10,  1000)
+
+        def assetInstanceList = []
+        def assetInstanceTotal
+        def filterParams = [:]
 
         // Quick Search:
         if(!params.filter) {
-           return [ assetInstanceList: Asset.list( params ), assetInstanceTotal: Asset.count() ]
-        }
+            assetInstanceList = Asset.list( params )
+            assetInstanceTotal = Asset.count()
+            filterParams.quickSearch = params.quickSearch
+        }
+        else {
         // filterPane:
-        return[ assetInstanceList: filterService.filter( params, Asset ),
-                assetInstanceTotal: filterService.count( params, Asset ),
-                filterParams: com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params),
-                params:params ]
-    }
+            assetInstanceList = filterService.filter( params, Asset )
+            assetInstanceTotal = filterService.count( params, Asset )
+            filterParams = com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params)
+        }
+
+        // export plugin:
+        if(params?.format && params.format != "html") {
+
+            def dateFmt = { date ->
+                formatDate(format: "EEE, dd-MMM-yyyy", date: date)
+            }
+
+//             def fmtAsset = { m ->
+//                     def r = ''
+//                     def assetInstance = Asset.findByName(m)
+// 
+//                     r +=  assetInstance
+//                     r += ", "
+// 
+//                     def  lastSubAsset = assetInstance.subAssets.size() - 1
+//                     assetInstance.subAssets.eachWithIndex() { obj, i ->
+//                         r += "\"" + obj + "\""
+//                         if( i < lastSubAsset )
+//                             r += ", "
+//                     }
+//                     return r
+//             }
+
+//             def fmtSubAsset = { m ->
+//                     def r = ''
+//                     m.each() {
+//                         def machine = Machine.findByName(it)
+//                         def assemblies = machine.assemblies
+//                         r += machine.name
+//                         r += " "
+//                         r += assemblies
+//                         r += " "
+//                     }
+//                     return r
+//             }
+
+            String title = "Asset List."
+
+            response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
+            response.setHeader("Content-disposition", "attachment; filename=tasks.${params.extension}")
+            List fields = ["section.site",
+                                "section",
+                                "name",
+                                "description"]
+            Map labels = ["section.site": "Site",
+                                "section": "Section",
+                                "name": "Asset",
+                                "description": "Description"]
+//             Map labels
+//             Map formatters = ["subAsset.name": fmtSubAsset]
+            Map formatters = [:]
+            Map parameters = [title: title, separator: ","]
+
+            exportService.export(params.format,
+                                                response.outputStream,
+                                                assetInstanceList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) },
+                                                fields,
+                                                labels,
+                                                formatters,
+                                                parameters)
+        }
+
+        // Add some basic params to filterParams.
+        filterParams.max = params.max
+        filterParams.offset = params.offset?.toInteger() ?: 0
+        filterParams.sort = params.sort ?: "id"
+        filterParams.order = params.order ?: "desc"
+
+        return[ assetInstanceList: assetInstanceList,
+                assetInstanceTotal: assetInstanceTotal,
+                filterParams: filterParams ]
+
+    } // end search()
 
     def show = {
@@ -113,4 +236,18 @@
     }
 
+    def copy = {
+        def assetToCopy = Asset.get(params.asset.id)
+
+        if(!assetToCopy) {
+            flash.message = "Please select an asset to copy."
+            redirect(action: list)
+            return
+        }
+
+        def assetInstance = new Asset(name: assetToCopy.name, section: assetToCopy.section)
+        assetInstance.properties = params
+        return ['assetInstance':assetInstance, assetToCopy: assetToCopy]
+    }
+
     def save = {
         def assetInstance = new Asset(params)
@@ -123,3 +260,107 @@
         }
     }
-}
+
+    def saveCopy = {
+        def result = saveCopySrvce(params)
+
+        if(!result.error) {
+            flash.message = g.message(code: "default.create.success", args: ["Asset", result.assetInstance.id])
+            redirect(action:show, id: result.assetInstance.id)
+            return
+        }
+
+        if(result.error.code == "default.not.found") {
+            flash.message = g.message(code: result.error.code, args: ["Asset", params.assetToCopy?.id])
+            redirect(action: list)
+            return
+        }
+
+        render(view:'copy', model:[assetInstance: result.assetInstance, assetToCopy: result.assetToCopy])
+    }
+
+    def saveCopySrvce(params) {
+        Asset.withTransaction { status ->
+            def result = [:]
+
+            def fail = { Map m ->
+                status.setRollbackOnly()
+                if(result.assetInstance && m.field)
+                    result.assetInstance.errors.rejectValue(m.field, m.code)
+                result.error = [ code: m.code, args: ["Asset", params.id] ]
+                return result
+            }
+
+            result.assetToCopy = Asset.get(params.assetToCopy?.id)
+            if(!result.assetToCopy)
+                return fail(code:"default.not.found")
+
+            result.assetInstance =  new Asset(params)
+
+            if(result.assetInstance.hasErrors() || !result.assetInstance.save())
+                return fail(code:"default.create.failure")
+
+            def assetSubItemInstance1
+
+            // Copy subItems from level 2 and bellow.
+            def copyAssetSubItem = { assetSubItemToCopy, parentItem ->
+                def assetSubItemInstance = new AssetSubItem(name: assetSubItemToCopy.name,
+                                                                                            description: assetSubItemToCopy.description,
+                                                                                            parentItem: parentItem)
+
+                if(assetSubItemInstance.hasErrors() || !assetSubItemInstance.save())
+                    return fail(field:"subItems", code:"default.create.failure")
+
+                def i = 0
+                for(assetSubItem in assetSubItemToCopy.subItems) {
+                    call(assetSubItem, assetSubItemInstance)
+                    // Protect against endless recurrsion.
+                    i++
+                    if(i > 100)
+                        fail(code:"default.create.failure")
+                    // Stop if an error is flagged.
+                    if(result.error)
+                        break
+                }
+            } //copyAssetSubItem
+
+            // Copy the 1st level of subItems.
+            def copyAssetSubItem1 = { assetSubItemToCopy ->
+                assetSubItemInstance1 = new AssetSubItem(name: assetSubItemToCopy.name,
+                                                                                        description: assetSubItemToCopy.description,
+                                                                                        asset: result.assetInstance)
+
+                if(assetSubItemInstance1.hasErrors() || !assetSubItemInstance1.save())
+                    return fail(field:"assetSubItems", code:"default.create.failure")
+
+                def i = 0
+                for(assetSubItem in assetSubItemToCopy.subItems) {
+                    copyAssetSubItem(assetSubItem, assetSubItemInstance1)
+                    // Protect against endless recurrsion.
+                    i++
+                    if(i > 100)
+                        fail(code:"default.create.failure")
+                    // Stop if an error is flagged.
+                    if(result.error)
+                        break
+                }
+            } //copyAssetSubItem1
+
+            def i = 0
+            for(assetSubItem in result.assetToCopy.assetSubItems) {
+                copyAssetSubItem1(assetSubItem)
+                // Protect against endless recurrsion.
+                i++
+                if(i > 100)
+                    fail(code:"default.create.failure")
+                // Stop if an error is flagged.
+                if(result.error)
+                    break
+            }
+
+            // Success or not.
+            return result
+
+        } //end withTransaction
+    } // end saveCopySrvce
+
+} // end class
Index: /trunk/grails-app/i18n/messages.properties
===================================================================
--- /trunk/grails-app/i18n/messages.properties	(revision 270)
+++ /trunk/grails-app/i18n/messages.properties	(revision 271)
@@ -1,2 +1,8 @@
+asset.tree.import.success=Asset tree imported.
+asset.tree.import.failure=Could not create asset tree from supplied file.
+asset.tree.import.file.over.max.size=Supplied file is over max size.
+asset.tree.import.file.not.supplied=No file supplied.
+asset.tree.import.no.header=The supplied file does not have the correct headers, please see the template file.
+
 sub.task.create.confirm=Immediately create and save a new sub task?
 
Index: /trunk/grails-app/services/CsvService.groovy
===================================================================
--- /trunk/grails-app/services/CsvService.groovy	(revision 271)
+++ /trunk/grails-app/services/CsvService.groovy	(revision 271)
@@ -0,0 +1,181 @@
+import au.com.bytecode.opencsv.CSVWriter
+import au.com.bytecode.opencsv.CSVReader
+
+/**
+ * Provides some csv import/export methods.
+ * Requires the opencsv jar to be available which is included in the grails-export plugin.
+ */
+class CsvService {
+
+    boolean transactional = false
+
+    /**
+    * Import an asset tree for a single asset.
+    * @param file A csv file containing the asset tree for a single asset.
+    */
+    def importAssetTree(request) {
+        def result = [:]
+
+        def megaByteMultiplier = 1000 * 1000
+        def fileMaxSize = 10 * megaByteMultiplier //Mb
+
+        def fail = { Map m ->
+            //status.setRollbackOnly()
+            result.error = [ code: m.code, args: ["Import Asset Tree"] ]
+            return result
+        }
+
+        def multiPartFile = request.getFile('file')
+
+        if(!multiPartFile || multiPartFile.isEmpty())
+            return fail(code: "asset.tree.import.file.not.supplied")
+
+        if (multiPartFile.getSize() > fileMaxSize)
+            return fail(code: "asset.tree.import.file.over.max.size")
+
+        InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
+        CSVReader reader = new CSVReader(sr)
+
+        def nextLine = reader.readNext()
+        def lineNumber = 1
+
+        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
+        if(nextLine != header)
+            return fail(code: "asset.tree.import.no.header")
+
+        nextLine = reader.readNext()
+        lineNumber ++
+
+        while(nextLine) {
+            lineNumber ++
+
+            println lineNumber + " : " + nextLine[0]
+
+//             if(nextLine[0]) {
+//                 if( !Site.findByName(nextLine[0].toString()) )
+//                     println nextLine[0]
+//             }
+
+            nextLine = reader.readNext()
+        } //while(nextLine)
+
+        // Success.
+        return result
+
+    } // end importAssetTree()
+
+    /**
+    * Build an asset tree template csv file.
+    * This template can then be populated for import.
+    * @returns The template as a String in csv format.
+    */
+    def buildAssetTreeTemplate() {
+
+        StringWriter sw = new StringWriter()
+        CSVWriter writer = new CSVWriter(sw)
+
+        //Header
+        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
+        writer.writeNext(header as String[])
+
+        //Rows
+        def row
+
+        row = []
+        writer.writeNext(row as String[]) //blank row between assets.
+
+        writer.close()
+        return sw.toString()
+    }
+
+    /**
+    * Build complete asset trees for export.
+    * @param assetList The list of assets to build and export trees for.
+    * @returns The tree as a String in csv format.
+    */
+    def buildAssetTree(List assetList) {
+
+        StringWriter sw = new StringWriter()
+        CSVWriter writer = new CSVWriter(sw)
+
+        //Header
+        def header = ["Site", "Section", "Asset", "Sub Asset", "Functional Assembly", "Sub Assembly Group"]
+        writer.writeNext(header as String[])
+
+        //Rows
+        def row
+
+        def writeAssetSubItem4 = { assetSubItem ->
+            row.add(assetSubItem)
+            writer.writeNext(row as String[])
+        }
+
+        def writeAssetSubItem3 = { assetSubItem ->
+            row.add(assetSubItem)
+
+            if(assetSubItem.subItems.size() > 0) {
+                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem4 ->
+                    writeAssetSubItem4(assetSubItem4)
+                    row.remove(row.last())
+                }
+            }
+            else {
+                writer.writeNext(row as String[])
+            }
+
+        }
+
+        def writeAssetSubItem2 = { assetSubItem ->
+            row.add(assetSubItem)
+
+            if(assetSubItem.subItems.size() > 0) {
+                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem3 ->
+                    writeAssetSubItem3(assetSubItem3)
+                    row.remove(row.last())
+                }
+            }
+            else {
+                writer.writeNext(row as String[])
+            }
+
+        }
+
+        def writeAssetSubItem1 = { assetSubItem ->
+            row.add(assetSubItem)
+
+            if(assetSubItem.subItems.size() > 0) {
+                assetSubItem.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { assetSubItem2 ->
+                    writeAssetSubItem2(assetSubItem2)
+                    row.remove(row.last())
+                }
+            }
+            else {
+                writer.writeNext(row as String[])
+            }
+
+        }
+
+        assetList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }.each() { asset ->
+            row = []
+            writer.writeNext(row as String[]) //blank row between assets.
+            row.add(asset.section.site)
+            row.add(asset.section)
+            row.add(asset.name)
+
+            if(asset.assetSubItems.size() > 0) {
+                asset.assetSubItems.each() { assetSubItem1 ->
+                    writeAssetSubItem1(assetSubItem1)
+                    row.remove(row.last())
+                }
+            }
+            else {
+                writer.writeNext(row as String[])
+            }
+
+        }
+
+        writer.close()
+        return sw.toString()
+    } // end buildAssetTree
+
+} // end class
Index: /trunk/grails-app/views/asset/edit.gsp
===================================================================
--- /trunk/grails-app/views/asset/edit.gsp	(revision 270)
+++ /trunk/grails-app/views/asset/edit.gsp	(revision 271)
@@ -83,10 +83,10 @@
                             <tr class="prop">
                                 <td valign="top" class="name">
-                                    <label for="assetSubItem">Asset Sub Item:</label>
+                                    <label for="assetSubItems">Asset Sub Items:</label>
                                 </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'assetSubItem','errors')}">
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'assetSubItems','errors')}">
                                     
 <ul>
-<g:each var="a" in="${assetInstance?.assetSubItem?}">
+<g:each var="a" in="${assetInstance?.assetSubItems?}">
     <li><g:link controller="assetSubItem" action="show" id="${a.id}">${a?.encodeAsHTML()}</g:link></li>
 </g:each>
Index: /trunk/grails-app/views/asset/show.gsp
===================================================================
--- /trunk/grails-app/views/asset/show.gsp	(revision 270)
+++ /trunk/grails-app/views/asset/show.gsp	(revision 271)
@@ -71,9 +71,9 @@
                     
                         <tr class="prop">
-                            <td valign="top" class="name">Asset Sub Item:</td>
+                            <td valign="top" class="name">Asset Sub Items:</td>
                             
                             <td  valign="top" style="text-align:left;" class="value">
                                 <ul>
-                                <g:each var="a" in="${assetInstance.assetSubItem}">
+                                <g:each var="a" in="${assetInstance.assetSubItems}">
                                     <li><g:link controller="assetSubItem" action="show" id="${a.id}">${a?.encodeAsHTML()}</g:link></li>
                                 </g:each>
Index: /trunk/grails-app/views/assetDetailed/copy.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/copy.gsp	(revision 271)
+++ /trunk/grails-app/views/assetDetailed/copy.gsp	(revision 271)
@@ -0,0 +1,83 @@
+
+
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+        <meta name="layout" content="main" />
+        <title>Create Asset Copy</title>
+        <nav:resources override="true"/>
+    </head>
+    <body>
+        <div class="nav">
+            <h1>Create Asset Copy</h1>
+        </div>
+        <div class="body">
+            <g:if test="${flash.message}">
+            <div class="message">${flash.message}</div>
+            </g:if>
+            <g:hasErrors bean="${assetInstance}">
+            <div class="errors">
+                <g:renderErrors bean="${assetInstance}" as="list" />
+            </div>
+            </g:hasErrors>
+            <g:form method="post" >
+                <g:hiddenField name="assetToCopy.id" value="${assetToCopy.id}" />
+                <div class="dialog">
+                    <table>
+                        <tbody>
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="name">Copying:</label>
+                                </td>
+                                <td valign="top" class="value">
+                                    ${assetToCopy.encodeAsHTML()}
+                                </td>
+                            </tr> 
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="name">Name:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'name','errors')}">
+                                    <input type="text" maxlength="50" id="name" name="name" value="${fieldValue(bean:assetInstance,field:'name')}"/>
+                                </td>
+                            </tr> 
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="description">Description:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'description','errors')}">
+                                    <input type="text" maxlength="100" id="description" name="description" value="${fieldValue(bean:assetInstance,field:'description')}"/>
+                                </td>
+                            </tr> 
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="isActive">Is Active:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'isActive','errors')}">
+                                    <g:checkBox name="isActive" value="${assetInstance?.isActive}" ></g:checkBox>
+                                </td>
+                            </tr> 
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="section">Section:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'section','errors')}">
+                                    <g:select optionKey="id" from="${Section.list()}" name="section.id" value="${assetInstance?.section?.id}" ></g:select>
+                                </td>
+                            </tr> 
+                        
+                        </tbody>
+                    </table>
+                </div>
+                <div class="buttons">
+                    <span class="button"><g:actionSubmit class="save" value="Create" action="saveCopy"/></span>
+                </div>
+            </g:form>
+        </div>
+    </body>
+</html>
Index: /trunk/grails-app/views/assetDetailed/create.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/create.gsp	(revision 270)
+++ /trunk/grails-app/views/assetDetailed/create.gsp	(revision 271)
@@ -5,5 +5,5 @@
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
         <meta name="layout" content="main" />
-        <title>Create Asset</title>   
+        <title>Create Asset</title>
         <nav:resources override="true"/>
     </head>
@@ -31,7 +31,7 @@
                                 </td>
                                 <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'name','errors')}">
-                                    <input type="text" id="name" name="name" value="${fieldValue(bean:assetInstance,field:'name')}"/>
+                                    <input type="text" maxlength="50" id="name" name="name" value="${fieldValue(bean:assetInstance,field:'name')}"/>
                                 </td>
-                            </tr>
+                            </tr> 
                         
                             <tr class="prop">
@@ -40,35 +40,8 @@
                                 </td>
                                 <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'description','errors')}">
-                                    <input type="text" id="description" name="description" value="${fieldValue(bean:assetInstance,field:'description')}"/>
-                                </td>
-                            </tr>
-                        
-                            <tr class="prop">
-                                <td valign="top" class="name">
-                                    <label for="costCode">Cost Code:</label>
-                                </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'costCode','errors')}">
-                                    <input type="text" id="costCode" name="costCode" value="${fieldValue(bean:assetInstance,field:'costCode')}"/>
-                                </td>
-                            </tr>
-                        
-                            <tr class="prop">
-                                <td valign="top" class="name">
-                                    <label for="assetType">Asset Type:</label>
-                                </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'assetType','errors')}">
-                                    <g:select optionKey="id" from="${AssetType.list()}" name="assetType.id" value="${assetInstance?.assetType?.id}" ></g:select>
+                                    <input type="text" maxlength="100" id="description" name="description" value="${fieldValue(bean:assetInstance,field:'description')}"/>
                                 </td>
                             </tr> 
-
-                            <tr class="prop">
-                                <td valign="top" class="name">
-                                    <label for="systemSection">System Section:</label>
-                                </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'systemSection','errors')}">
-                                    <g:select optionKey="id" from="${SystemSection.list()}" name="systemSection.id" value="${assetInstance?.systemSection?.id}" ></g:select>
-                                </td>
-                            </tr>
-
+                        
                             <tr class="prop">
                                 <td valign="top" class="name">
@@ -79,5 +52,14 @@
                                 </td>
                             </tr> 
-
+                        
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="section">Section:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'section','errors')}">
+                                    <g:select optionKey="id" from="${Section.list()}" name="section.id" value="${assetInstance?.section?.id}" ></g:select>
+                                </td>
+                            </tr> 
+                        
                         </tbody>
                     </table>
Index: /trunk/grails-app/views/assetDetailed/edit.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/edit.gsp	(revision 270)
+++ /trunk/grails-app/views/assetDetailed/edit.gsp	(revision 271)
@@ -33,5 +33,5 @@
                                 </td>
                                 <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'name','errors')}">
-                                    <input type="text" id="name" name="name" value="${fieldValue(bean:assetInstance,field:'name')}"/>
+                                    <input type="text" maxlength="50" id="name" name="name" value="${fieldValue(bean:assetInstance,field:'name')}"/>
                                 </td>
                             </tr> 
@@ -42,35 +42,26 @@
                                 </td>
                                 <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'description','errors')}">
-                                    <input type="text" id="description" name="description" value="${fieldValue(bean:assetInstance,field:'description')}"/>
+                                    <input type="text" maxlength="100" id="description" name="description" value="${fieldValue(bean:assetInstance,field:'description')}"/>
                                 </td>
-                            </tr>
+                            </tr> 
                         
                             <tr class="prop">
                                 <td valign="top" class="name">
-                                    <label for="costCode">Cost Code:</label>
+                                    <label for="isActive">Is Active:</label>
                                 </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'costCode','errors')}">
-                                    <input type="text" id="costCode" name="costCode" value="${fieldValue(bean:assetInstance,field:'costCode')}"/>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'isActive','errors')}">
+                                    <g:checkBox name="isActive" value="${assetInstance?.isActive}" ></g:checkBox>
                                 </td>
-                            </tr>
+                            </tr> 
                         
                             <tr class="prop">
                                 <td valign="top" class="name">
-                                    <label for="assetType">Asset Type:</label>
+                                    <label for="section">Section:</label>
                                 </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'assetType','errors')}">
-                                    <g:select optionKey="id" from="${AssetType.list()}" name="assetType.id" value="${assetInstance?.assetType?.id}" ></g:select>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'section','errors')}">
+                                    <g:select optionKey="id" from="${Section.list()}" name="section.id" value="${assetInstance?.section?.id}" ></g:select>
                                 </td>
-                            </tr>
+                            </tr> 
                         
-                            <tr class="prop">
-                                <td valign="top" class="name">
-                                    <label for="systemSection">System Section:</label>
-                                </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'systemSection','errors')}">
-                                    <g:select optionKey="id" from="${SystemSection.list()}" name="systemSection.id" value="${assetInstance?.systemSection?.id}" ></g:select>
-                                </td>
-                            </tr>
-                         
                             <tr class="prop">
                                 <td valign="top" class="name">
@@ -91,8 +82,15 @@
                             <tr class="prop">
                                 <td valign="top" class="name">
-                                    <label for="isActive">Is Active:</label>
+                                    <label for="assetSubItems">Asset Sub Items:</label>
                                 </td>
-                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'isActive','errors')}">
-                                    <g:checkBox name="isActive" value="${assetInstance?.isActive}" ></g:checkBox>
+                                <td valign="top" class="value ${hasErrors(bean:assetInstance,field:'assetSubItems','errors')}">
+                                    
+<ul>
+<g:each var="a" in="${assetInstance?.assetSubItems?}">
+    <li><g:link controller="assetSubItemDetailed" action="show" id="${a.id}">${a?.encodeAsHTML()}</g:link></li>
+</g:each>
+</ul>
+<g:link controller="assetSubItemDetailed" params="['asset.id':assetInstance?.id]" action="create">Add AssetSubItem</g:link>
+
                                 </td>
                             </tr> 
Index: /trunk/grails-app/views/assetDetailed/importAssetTree.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/importAssetTree.gsp	(revision 271)
+++ /trunk/grails-app/views/assetDetailed/importAssetTree.gsp	(revision 271)
@@ -0,0 +1,35 @@
+<html>
+    <head>
+        <meta name="layout" content="main" />
+        <title>Import Asset Tree</title>
+        <nav:resources override="true"/>
+        <g:render template="/shared/pictureHead" />
+    </head>
+    <body>
+        <div class="nav">
+            <h1>Import Asset Tree</h1>
+        </div>
+        <div class="body">
+            <g:render template="/shared/messages" />
+            <g:uploadForm action="importAssetTreeSave" enctype="multipart/form-data" onsubmit="return Lightbox.loading();">
+                <div class="dialog">
+                    <table>
+                        <tbody>
+                            <tr class="prop">
+                                <td valign="top" class="name">
+                                    <label for="file">File:</label>
+                                </td>
+                                <td valign="top" class="value ${hasErrors(bean: picture, field: 'file', 'errors')}">
+                                    <input type="file" id="file" name="file" size="40"/>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+                <div class="buttons">
+                    <span class="button"><input class="save" type="submit" value="Create" /></span>
+                </div>
+            </g:uploadForm>
+        </div>
+    </body>
+</html>
Index: /trunk/grails-app/views/assetDetailed/list.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/list.gsp	(revision 270)
+++ /trunk/grails-app/views/assetDetailed/list.gsp	(revision 271)
@@ -22,14 +22,12 @@
                         
                    	        <g:sortableColumn property="id" title="Id" />
-
-                             <g:sortableColumn property="name" title="Name" />
-
-                             <g:sortableColumn property="assetType" title="Asset Type" />
                         
-                   	        <g:sortableColumn property="systemSection" title="System Section" />
-
-                            <g:sortableColumn property="isActive" title="Is Active" />
-
-                            <th></th>
+                   	        <g:sortableColumn property="name" title="Name" />
+                        
+                   	        <g:sortableColumn property="description" title="Description" />
+                        
+                   	        <g:sortableColumn property="isActive" title="Is Active" />
+                        
+                   	        <th>Section</th>
                    	    
                         </tr>
@@ -40,12 +38,12 @@
                         
                             <td>${fieldValue(bean:assetInstance, field:'id')}</td>
-
-                            <td>${fieldValue(bean:assetInstance, field:'name')}</td>                        
-
-                            <td>${fieldValue(bean:assetInstance, field:'assetType')}</td>
-
-                            <td>${fieldValue(bean:assetInstance, field:'systemSection')}</td>
-
+                        
+                            <td>${fieldValue(bean:assetInstance, field:'name')}</td>
+                        
+                            <td>${fieldValue(bean:assetInstance, field:'description')}</td>
+                        
                             <td>${fieldValue(bean:assetInstance, field:'isActive')}</td>
+                        
+                            <td>${fieldValue(bean:assetInstance, field:'section')}</td>
 
                             <td>
Index: /trunk/grails-app/views/assetDetailed/search.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/search.gsp	(revision 270)
+++ /trunk/grails-app/views/assetDetailed/search.gsp	(revision 271)
@@ -8,4 +8,5 @@
         <nav:resources override="true"/>
         <filterpane:includes />
+        <export:resource />
     </head>
     <body>
@@ -39,10 +40,10 @@
 
                              <g:sortableColumn property="name" title="Name" params="${filterParams}" />
-
-                             <g:sortableColumn property="assetType" title="Asset Type" params="${filterParams}" />
                         
-                   	        <g:sortableColumn property="systemSection" title="System Section" params="${filterParams}" />
+                            <g:sortableColumn property="description" title="Description" params="${filterParams}" />
 
                             <g:sortableColumn property="isActive" title="Is Active" params="${filterParams}" />
+                        
+                            <g:sortableColumn property="section" title="Section" params="${filterParams}" />
 
                             <th></th>
@@ -58,9 +59,9 @@
                             <td>${fieldValue(bean:assetInstance, field:'name')}</td>                        
 
-                            <td>${fieldValue(bean:assetInstance, field:'assetType')}</td>
-
-                            <td>${fieldValue(bean:assetInstance, field:'systemSection')}</td>
+                            <td>${fieldValue(bean:assetInstance, field:'description')}</td>
 
                             <td>${fieldValue(bean:assetInstance, field:'isActive')}</td>
+
+                            <td>${fieldValue(bean:assetInstance, field:'section')}</td>
 
                             <td>
@@ -78,4 +79,18 @@
                 <g:paginate total="${assetInstanceTotal}" params="${filterParams}" />
             </div>
+            <export:formats  params="${filterParams}" formats="['csv', 'excel', 'pdf', 'rtf']"/>
+            <br />
+            Asset Tree:
+            <g:link action="exportAssetTree">
+                Export
+            </g:link>
+            /
+            <g:link action="exportAssetTreeTemplate">
+                Template
+            </g:link>
+            /
+            <g:link action="importAssetTree">
+                Import
+            </g:link>
 
             <filterpane:filterPane domainBean="Asset"
@@ -84,7 +99,6 @@
                                     class="overlayPane"
                                     excludeProperties=""
-                                    associatedProperties="systemSection.name, assetType.name"
-                                    filterPropertyValues="${['systemSection.name':[values:SystemSection.list()],
-                                                                        'assetType.name':[values:AssetType.list()] ]}" />
+                                    associatedProperties="section.name"
+                                    filterPropertyValues="${['section.name':[values:Section.list()] ]}" />
         </div> <!-- end body div -->
     </body>
Index: /trunk/grails-app/views/assetDetailed/show.gsp
===================================================================
--- /trunk/grails-app/views/assetDetailed/show.gsp	(revision 270)
+++ /trunk/grails-app/views/assetDetailed/show.gsp	(revision 271)
@@ -19,5 +19,4 @@
                 <table>
                     <tbody>
-
                     
                         <tr class="prop">
@@ -29,8 +28,55 @@
                     
                         <tr class="prop">
-                            <td valign="top" class="name">Name:</td>
-                            
-                            <td valign="top" class="value">${fieldValue(bean:assetInstance, field:'name')}</td>
-                            
+                            <td valign="top" class="name">Asset:</td>
+
+                            <td  valign="top" style="text-align:left;" class="value">
+                                ${assetInstance.encodeAsHTML()}
+                                <g:link controller="assetSubItemDetailed" params="['asset.id':assetInstance?.id]" action="create">
+                                    <img src="${resource(dir:'images/skin',file:'database_add.png')}" alt="Add" title="Add Sub Item"/>
+                                </g:link>
+                                <g:link params="['asset.id':assetInstance?.id]" action="copy">
+                                    <img src="${resource(dir:'images/skin',file:'page_copy.png')}" alt="Copy" title="Copy Asset"/>
+                                </g:link>
+                                <br />
+                                <br />
+                                <ul>
+                                <g:each var="assetSubItem1" in="${assetInstance.assetSubItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
+                                    <li>
+                                        <g:link controller="assetSubItemDetailed" action="edit" id="${assetSubItem1.id}">${assetSubItem1?.encodeAsHTML()}</g:link>
+                                    <g:link controller="assetSubItemDetailed" params="['parentItem.id':assetSubItem1?.id]" action="create">
+                                        <img src="${resource(dir:'images/skin',file:'database_add.png')}" alt="Add" title="Add Sub Item" />
+                                    </g:link>
+                                    </li>
+                                    <ul>
+                                    <g:each var="assetSubItem2" in="${assetSubItem1.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
+                                        <li>
+                                            <g:link controller="assetSubItemDetailed" action="edit" id="${assetSubItem2.id}">${assetSubItem2?.encodeAsHTML()}</g:link>
+                                        <g:link controller="assetSubItemDetailed" params="['parentItem.id':assetSubItem2?.id]" action="create">
+                                            <img src="${resource(dir:'images/skin',file:'database_add.png')}" alt="Add" title="Add Sub Item" />
+                                        </g:link>
+                                        </li>
+                                        <ul>
+                                        <g:each var="assetSubItem3" in="${assetSubItem2.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
+                                            <li>
+                                                <g:link controller="assetSubItemDetailed" action="edit" id="${assetSubItem3.id}">${assetSubItem3?.encodeAsHTML()}</g:link>
+                                            <g:link controller="assetSubItemDetailed" params="['parentItem.id':assetSubItem3?.id]" action="create">
+                                                <img src="${resource(dir:'images/skin',file:'database_add.png')}" alt="Add" title="Add Sub Item" />
+                                            </g:link>
+                                            </li>
+                                            <ul>
+                                            <g:each var="assetSubItem4" in="${assetSubItem3.subItems.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
+                                                <li><g:link controller="assetSubItemDetailed" action="edit" id="${assetSubItem4.id}">${assetSubItem4?.encodeAsHTML()}</g:link></li>
+                                            </g:each> <!--assetSubItem4-->
+                                            </ul>
+                                        </g:each> <!--assetSubItem3-->
+                                        </ul>
+                                    </g:each> <!--assetSubItem2-->
+                                    </ul>
+                                    <br />
+                                    <br />
+                                </g:each> <!--assetSubItem1-->
+                                </ul>
+                            </td>
+
                         </tr>
                     
@@ -39,52 +85,4 @@
                             
                             <td valign="top" class="value">${fieldValue(bean:assetInstance, field:'description')}</td>
-                            
-                        </tr>
-                    
-                        <tr class="prop">
-                            <td valign="top" class="name">Cost Code:</td>
-                            
-                            <td valign="top" class="value">${fieldValue(bean:assetInstance, field:'costCode')}</td>
-                            
-                        </tr>
-                    
-                        <tr class="prop">
-                            <td valign="top" class="name">Asset Type:</td>
-                            
-                            <td valign="top" class="value">
-                                ${assetInstance?.assetType?.encodeAsHTML()}
-                                <ul>
-                                <g:each var="a" in="${assetInstance.assetType.assemblies}">
-                                    <li>
-                                        ${a?.encodeAsHTML()}
-                                        <ul>
-                                        <g:each var="s" in="${a.subAssemblies}">
-                                            <li>${s?.encodeAsHTML()}</li>
-                                        </g:each>
-                                        </ul>
-                                    </li>
-                                </g:each>
-                                </ul>
-                            </td>
-                            
-                        </tr>
-
-                        <tr class="prop">
-                            <td valign="top" class="name">System Section:</td>
-                            
-                            <td valign="top" class="value"><g:link controller="systemSectionDetailed" action="show" id="${assetInstance?.systemSection?.id}">${assetInstance?.systemSection?.encodeAsHTML()}</g:link></td>
-                            
-                        </tr>
-                    
-                        <tr class="prop">
-                            <td valign="top" class="name">Asset Extended Attributes:</td>
-                            
-                            <td  valign="top" style="text-align:left;" class="value">
-                                <ul>
-                                <g:each var="a" in="${assetInstance.assetExtendedAttributes}">
-                                    <li><g:link controller="assetExtendedAttributeDetailed" action="show" id="${a.id}">${a?.encodeAsHTML()}</g:link></li>
-                                </g:each>
-                                </ul>
-                            </td>
                             
                         </tr>
@@ -98,4 +96,24 @@
                     
                         <tr class="prop">
+                            <td valign="top" class="name">Section:</td>
+                            
+                            <td valign="top" class="value"><g:link controller="sectionDetailed" action="show" id="${assetInstance?.section?.id}">${assetInstance?.section?.encodeAsHTML()}</g:link></td>
+                            
+                        </tr>
+                    
+                        <tr class="prop">
+                            <td valign="top" class="name">Asset Extended Attributes:</td>
+                            
+                            <td  valign="top" style="text-align:left;" class="value">
+                                <ul>
+                                <g:each var="a" in="${assetInstance.assetExtendedAttributes}">
+                                    <li><g:link controller="assetExtendedAttributeDetailed" action="edit" id="${a.id}">${a?.encodeAsHTML()}</g:link></li>
+                                </g:each>
+                                </ul>
+                            </td>
+                            
+                        </tr>
+                    
+                        <tr class="prop">
                             <td valign="top" class="name">Maintenance Actions:</td>
                             
@@ -103,5 +121,5 @@
                                 <ul>
                                 <g:each var="m" in="${assetInstance.maintenanceActions}">
-                                    <li><g:link controller="maintenanceActionDetailed" action="show" id="${m.id}">${m?.encodeAsHTML()}</g:link></li>
+                                    <li><g:link controller="maintenanceActionDetailed" action="edit" id="${m.id}">${m?.encodeAsHTML()}</g:link></li>
                                 </g:each>
                                 </ul>
