Index: trunk/grails-app/domain/Image.groovy
===================================================================
--- trunk/grails-app/domain/Image.groovy	(revision 182)
+++ trunk/grails-app/domain/Image.groovy	(revision 182)
@@ -0,0 +1,52 @@
+class Image implements Comparable {
+
+    Picture picture
+    Integer size
+    byte[] data
+    String contentType
+    Integer width
+    Integer height
+    Date dateCreated = new Date()
+    Date lastUpdated = new Date()
+
+    static belongsTo = [ Picture ]
+
+    static mapping = {
+        picture index: 'images_index', unique: true
+        size index: 'images_index', unique: true
+        data type: 'binary'
+    }
+
+    static constraints = {
+        data(maxSize: MAX_SIZE)
+    }
+
+    static final Integer MAX_SIZE = 10 * 1024 * 1024
+
+    static final Integer Original = 1
+    static final Integer Large = 2
+    static final Integer Medium = 3
+    static final Integer Small = 4
+
+    static final Integer[] Widths =  [ 0, 0, 500, 250, 100 ]
+    static final Integer[] Heights = [ 0, 0, 500, 250, 100 ]
+
+    static final String[] Names = [ '', 'Original', 'Large', 'Medium', 'Small' ]
+
+    int compareTo(obj) {
+        size.compareTo(obj.size)
+    }
+
+    String filename() {
+        Image.filename(picture.id, size)
+    }
+
+    static String filename(long id, int size) {
+        if (size == Original) {
+            return "${id}-${Names[size]}.jpg"
+        }
+        else {
+            return "${id}-${Names[size]}.png"
+        }
+    }
+}
Index: trunk/grails-app/domain/InventoryItem.groovy
===================================================================
--- trunk/grails-app/domain/InventoryItem.groovy	(revision 181)
+++ trunk/grails-app/domain/InventoryItem.groovy	(revision 182)
@@ -5,4 +5,5 @@
     InventoryLocation inventoryLocation
     Period averageDeliveryPeriod
+    Picture picture
     String name
     String description = ""
@@ -17,4 +18,8 @@
     boolean enableReorder = true
 
+    static mapping = {
+        picture cascade: 'all-delete-orphan', lazy: true, inverse: true
+    }
+
     static hasMany = [alternateItems: InventoryItem,
                                     spareFor: Asset,
@@ -26,4 +31,5 @@
 
     static constraints = {
+        picture(nullable:true)
         name(unique:true, blank:false, maxSize:50)
         description()
@@ -45,3 +51,2 @@
     String toString() {"${this.name}"}
 }
-        
Index: trunk/grails-app/domain/Picture.groovy
===================================================================
--- trunk/grails-app/domain/Picture.groovy	(revision 182)
+++ trunk/grails-app/domain/Picture.groovy	(revision 182)
@@ -0,0 +1,32 @@
+class Picture {
+
+    InventoryItem inventoryItem
+    SortedSet images
+    String file
+    Integer operation
+    String contentType
+    Integer width
+    Integer height
+    Date dateCreated = new Date()
+    Date lastUpdated = new Date()
+
+    static belongsTo = [ InventoryItem ]
+    static hasMany = [ images : Image ]
+
+    static transients = [ 'file', 'operation']
+
+    static constraints = {
+    }
+
+    static mapping = {
+        images cascade: 'all-delete-orphan', inverse: true
+    }
+
+    static final Integer NoOp = 0
+    static final Integer RotateClockWise90 = 1
+    static final Integer RotateAntiClockWise90 = 2
+    static final Integer Rotate180 = 3
+    static final Integer Flip = 4
+    static final Integer Flop = 5
+
+}
