Index: /trunk/grails-app/services/CsvService.groovy
===================================================================
--- /trunk/grails-app/services/CsvService.groovy	(revision 314)
+++ /trunk/grails-app/services/CsvService.groovy	(revision 315)
@@ -1,4 +1,5 @@
 import au.com.bytecode.opencsv.CSVWriter
 import au.com.bytecode.opencsv.CSVReader
+import org.apache.commons.lang.WordUtils
 
 /**
@@ -93,5 +94,4 @@
                     log.info "No more columns on line: " + lineNumber
                     return false
-
                 }
                 if(!line[columnIndex]) {
@@ -99,6 +99,9 @@
                     return false
                 }
-                column.name = line[columnIndex]
-                column.description = line[++columnIndex]
+                // Capitalise and assign the name and description columns.
+                use(WordUtils) {
+                column.name = line[columnIndex].trim().capitalize()
+                column.description = line[++columnIndex].trim().capitalize()
+                }
                 columnIndex++
                 // Success.
@@ -106,4 +109,5 @@
             }
 
+            // Primary loop.
             while(line) {
                 numberOfColumns = Math.min( line.size(), maxNumberOfColumns )
@@ -116,5 +120,5 @@
 
                 // Ignore comment lines.
-                if( column.name.startsWith("Comment") ) {
+                if(line.toString().toLowerCase().contains("comment")) {
                     log.info "Comment line found."
                     nextLine()
@@ -123,5 +127,5 @@
 
                 // Ignore example lines.
-                if( column.name.startsWith("Example") ) {
+                if(line.toString().toLowerCase().contains("example")) {
                     log.info "Example line found."
                     nextLine()
@@ -129,4 +133,5 @@
                 }
 
+                // Site.
                 siteInstance = Site.findByName(column.name)
                 if(!siteInstance) {
@@ -146,4 +151,5 @@
                 }
 
+                // Department.
                 departmentInstance = Department.findByName(column.name)
                 if(!departmentInstance) {
@@ -164,4 +170,5 @@
                 }
 
+                // Section.
                 sectionInstance = Section.findByName(column.name)
                 if(!sectionInstance) {
@@ -183,4 +190,5 @@
                 }
 
+                // Asset.
                 assetInstance = Asset.findByName(column.name)
                 if(!assetInstance) {
@@ -201,4 +209,5 @@
                 }
 
+                // AssetSubItem Level 1.
                 assetSubItemInstance = AssetSubItem.findByName(column.name)
                 if(!assetSubItemInstance) {
@@ -215,4 +224,5 @@
                 assetInstance.addToAssetSubItems(assetSubItemInstance)
 
+                // Remaining AssetSubItems.
                 while( nextColumn() ) {
 
@@ -229,5 +239,5 @@
                         }
                     }
-                else log.info "Existing asset sub item: " + assetSubItemInstance
+                    else log.info "Existing asset sub item: " + assetSubItemInstance
 
                 } // while( nextColumn() )
@@ -268,11 +278,13 @@
         writer.writeNext(["Example: Site1", "", "Department 1", "", "Section 1", "", "Asset 2", ""] as String[])
         writer.writeNext()
-        writer.writeNext("Comment: the first two header lines are required.")
-        writer.writeNext("Comment: leave a blank line between assets.")
-        writer.writeNext("Comment: names are required, descriptions are optional.")
-        writer.writeNext("Comment: identical names in each column will be considered as the same item.")
-        writer.writeNext("Comment: any line starting with 'Comment' will be ignored.")
-        writer.writeNext("Comment: any line starting with 'Example' will be ignored.")
-        writer.writeNext("Comment: example and comment lines may be deleted.")
+        writer.writeNext("Comment: The first two header lines are required.")
+        writer.writeNext("Comment: Leave a blank line between assets.")
+        writer.writeNext("Comment: Names are required, descriptions are optional.")
+        writer.writeNext("Comment: Identical and existing names will be considered as the same item.")
+        writer.writeNext("Comment: An asset may share the first level of asset sub items with other assets.")
+        writer.writeNext("Comment: Lower levels of asset sub items are only parented once but may have many children.")
+        writer.writeNext("Comment: Lines containing 'comment' will be ignored.")
+        writer.writeNext("Comment: Lines containing 'example' will be ignored.")
+        writer.writeNext("Comment: This file must be saved as a CSV file before import.")
         writer.writeNext()
     }
@@ -324,7 +336,5 @@
         CSVWriter writer = new CSVWriter(sw)
 
-        //Header
-        writer.writeNext(templateHeaderLine1 as String[])
-        writer.writeNext(templateHeaderLine2 as String[])
+        writeTemplateLines(writer)
 
         //Rows
@@ -332,10 +342,12 @@
 
         def writeAssetSubItem4 = { assetSubItem ->
-            row.add(assetSubItem)
+            row.add(assetSubItem.name)
+            row.add(assetSubItem.description)
             writer.writeNext(row as String[])
         }
 
         def writeAssetSubItem3 = { assetSubItem ->
-            row.add(assetSubItem)
+            row.add(assetSubItem.name)
+            row.add(assetSubItem.description)
 
             if(assetSubItem.subItems.size() > 0) {
@@ -343,4 +355,5 @@
                     writeAssetSubItem4(assetSubItem4)
                     row.remove(row.last())
+                    row.remove(row.last())
                 }
             }
@@ -352,5 +365,6 @@
 
         def writeAssetSubItem2 = { assetSubItem ->
-            row.add(assetSubItem)
+            row.add(assetSubItem.name)
+            row.add(assetSubItem.description)
 
             if(assetSubItem.subItems.size() > 0) {
@@ -358,4 +372,5 @@
                     writeAssetSubItem3(assetSubItem3)
                     row.remove(row.last())
+                    row.remove(row.last())
                 }
             }
@@ -367,5 +382,6 @@
 
         def writeAssetSubItem1 = { assetSubItem ->
-            row.add(assetSubItem)
+            row.add(assetSubItem.name)
+            row.add(assetSubItem.description)
 
             if(assetSubItem.subItems.size() > 0) {
@@ -373,4 +389,5 @@
                     writeAssetSubItem2(assetSubItem2)
                     row.remove(row.last())
+                    row.remove(row.last())
                 }
             }
@@ -384,7 +401,12 @@
             row = []
             writer.writeNext(row as String[]) //blank row between assets.
-            row.add(asset.section.site)
-            row.add(asset.section)
+            row.add(asset.section.site.name)
+            row.add(asset.section.site.description)
+            row.add(asset.section.department.name)
+            row.add(asset.section.department.description)
+            row.add(asset.section.name)
+            row.add(asset.section.description)
             row.add(asset.name)
+            row.add(asset.description)
 
             if(asset.assetSubItems.size() > 0) {
@@ -392,4 +414,5 @@
                     writeAssetSubItem1(assetSubItem1)
                     row.remove(row.last())
+                    row.remove(row.last())
                 }
             }
