<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>controller/controller.rb</filename>
    </added>
    <added>
      <filename>controller/jukebox.rb</filename>
    </added>
    <added>
      <filename>helper/highlight.rb</filename>
    </added>
    <added>
      <filename>model/array.rb</filename>
    </added>
    <added>
      <filename>view/albums.xhtml</filename>
    </added>
    <added>
      <filename>view/browser.xhtml</filename>
    </added>
    <added>
      <filename>view/context_menu.xhtml</filename>
    </added>
    <added>
      <filename>view/jukebox/index.xhtml</filename>
    </added>
    <added>
      <filename>view/source/filter.xhtml</filename>
    </added>
    <added>
      <filename>view/tracklist.xhtml</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -4,11 +4,6 @@ class MainController &lt; Ramaze::Controller
   layout '/app'
 
   def index
-  end
-  
-  private
-
-  def title
-    @title || 'iTunes'
+    redirect R(JukeboxController)
   end
 end</diff>
      <filename>controller/main.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,6 @@ class PlaylistController &lt; Ramaze::Controller
   layout '/app'
   
   def list source_id, playlist_id
-    @source = Source.get(source_id)
-    @playlist = Playlist.get(source_id, playlist_id)
+    @tracks = Playlist.get(source_id, playlist_id).tracks
   end
 end
\ No newline at end of file</diff>
      <filename>controller/playlist.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,14 @@
 class SourceController &lt; Ramaze::Controller
   map '/source'
   layout '/app'
+
+  deny_layout :filter
   
   def list source_id
-    @source = Source.get(source_id)
-    @playlist = @source.main_playlist
+    @tracks = Source.get(source_id).library_playlist.tracks
+  end
+  
+  def filter
+    @tracks = Source.get(request[:source_id]).library_playlist.filter(request)
   end
 end
\ No newline at end of file</diff>
      <filename>controller/source.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,23 @@
 class TrackController &lt; Ramaze::Controller
   map '/track'
-  layout '/app'
   
-  def play source_id, playlist_id, track_id
-    Track.get(source_id, playlist_id, track_id).play
-    redirect_referer
+  def queue *parts
+    Itunes.get.jukebox &lt;&lt; get_tracks(*parts)
+    respond ' '
+  end
+  
+  def play *parts
+    Itunes.get.play_now(get_tracks(*parts))
+    respond ' '
+  end
+  
+  private
+  
+  def get_tracks *args
+    if request.post?
+      request.body.readlines.map { |path| Track.get(path) }
+    else
+      [Track.get(*args)]
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>controller/track.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,19 @@
-require 'rbosa'
-
 class Itunes &lt; OSAWrapper
   def self.get
     @itunes ||= self.new(OSA.app('iTunes'))
   end
   
-  attr_reader :sources
+  attr_reader :sources, :library, :jukebox
   
   def reindex
-    @sources = {}
-    
-    @obj.sources.each do |s|
-      @sources[s.id2] = Source.new(s)
-    end
+    @sources = @obj.sources.select{ |s| s.name != 'Radio' }.collect{ |s| Source.new(s) }
+    @library = @sources.find { |s| s.library? }
+    @jukebox = @library.jukebox_playlist
+  end
+  
+  def play_now tracks
+    index = @jukebox.tracks.length
+    @jukebox &lt;&lt; tracks
+    @jukebox.tracks[index].play
   end
 end
\ No newline at end of file</diff>
      <filename>model/itunes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,41 @@
 class Playlist &lt; OSAWrapper
   def self.get source_id, playlist_id
-    Itunes.get.sources[source_id.to_i].playlists[playlist_id.to_i]
+    Source.get(source_id).playlists.find { |p| p.id2 == playlist_id.to_i }
   end
   
-  cache_methods :tracks
+  attr_reader :tracks, :source
+  
+  def initialize obj, source
+    @obj = obj
+    @source = source
+    reindex
+  end
   
   def reindex
-    puts &quot;reindexing playlist: #{name}&quot;
+    Ramaze::Inform::info &quot;reindexing playlist: #{name}&quot;
+    
+    @tracks = @obj.tracks.collect { |t| Track.new(t, self) }
+  end
+  
+  def &lt;&lt; *args
+    args.flatten.each do |track|
+      track.duplicate(@obj)
+    end
+    
+    reindex
+  end
+  
+  def filter filters
+    tracks = @tracks
+    
+    [:artist, :album].each do |field|
+      unless filters[field].to_s.empty?
+        tracks = tracks.select { |t|
+          t.send(field).downcase == filters[field].downcase
+        }
+      end
+    end
+    
+    tracks
   end
 end
\ No newline at end of file</diff>
      <filename>model/playlist.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,23 +1,38 @@
 class Source &lt; OSAWrapper
-  def self.get id
-    Itunes.get.sources[id.to_i]
+  def self.get source_id
+    Itunes.get.sources.find { |s| s.id2 == source_id.to_i }
   end
   
-  attr_reader :playlists, :main_playlist
+  attr_reader :playlists, :library_playlist, :jukebox_playlist
   
   def reindex
-    puts &quot;reindexing source: #{name}&quot;
+    Ramaze::Inform::info &quot;reindexing source: #{name}&quot;
     
-    @playlists = {}
+    @playlists = @obj.user_playlists.collect { |p| Playlist.new(p, self) }
     
-    @obj.playlists.each do |p|
-      @playlists[p.id2] = Playlist.new(p)
+    if library?
+      if @jukebox_playlist = @playlists.find { |p| p.name == jukebox_playlist_name }
+        @playlists.delete(@jukebox_playlist)
+      end
     end
     
-    @main_playlist = @playlists.values.find { |p| p.name == self.name }
+    if music_playlist = @playlists.find{ |p| p.name == 'Music' }
+      @library_playlist = Playlist.new(music_playlist, self)
+      # @playlists.delete(music_playlist)
+    else
+      @library_playlist = Playlist.new(@obj.library_playlists.first, self)
+    end
+  end
+
+  def jukebox_playlist_name
+    'Jukebox'
+  end
+  
+  def library?
+    name == 'Library'
   end
   
   def tracks
-    main_playlist.tracks
+    library_playlist.tracks
   end
 end
\ No newline at end of file</diff>
      <filename>model/source.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,16 +1,50 @@
 class Track &lt; OSAWrapper
-  def self.get source_id, playlist_id, track_id
-    Itunes.get.sources[source_id.to_i].playlists[playlist_id.to_i].tracks.select { |t| t.id2 == track_id.to_i }
+  def self.get *args
+    path = args.first.to_s
+    
+    if path.include?('/')
+      get(*path.split('/'))
+    else
+      Playlist.get(args[0], args[1]).tracks.find { |t| t.id2 == args[2].to_i }
+    end
   end
   
-  cache_methods :artist, :album, :track_number
+  cache_methods :artist, :album, :duration
+
+  attr_reader :playlist
   
-  def initialize obj
+  def initialize obj, playlist
     @obj = obj
+    @playlist = playlist
     reindex
   end
   
-  def sort_key
-    [artist, album, track_number, name]
+  def current?
+    Itunes.get.player_state == OSA::ITunes::EPLS::PLAYING and Itunes.get.current_track.persistent_id == self.persistent_id
+  end
+  
+  def path
+    path_parts.join('/')
+  end
+  
+  def path_parts
+    begin
+      [@playlist.source.id2, @playlist.id2, id2]
+    rescue
+      Ramaze::Inform::info self.inspect
+      raise
+    end
+  end
+  
+  def time
+    duration ? (&quot;%d:%02d&quot; % duration.divmod(60)) : ''
+  end
+  
+  def self.get_artists tracks
+    tracks.collect{ |t| t.artist }.uniq.sort
+  end
+
+  def self.get_albums tracks
+    tracks.collect{ |t| t.album }.uniq.sort
   end
 end
\ No newline at end of file</diff>
      <filename>model/track.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,13 +16,93 @@
     bottom: 0;
     left: 20%;
     margin-left: 1px;
-    overflow: auto;
 }
 
-#content table {
-    width: 100%;
+#browser {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    height: 0;
+    overflow: hidden;
+
+    /* toggled by JS */
+    display: none;
+}
+
+#browser ul#artists {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 50%;
+    bottom: 0;
+    overflow-x: hidden;
+    overflow-y: auto;
+}
+
+#browser ul#albums {
+    position: absolute;
+    top: 0;
+    left: 50%;
+    right: 0;
+    bottom: 0;
+    overflow-x: hidden;
+    overflow-y: auto;
+}
+
+#tracklist {
+    position: absolute;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    top: 0;
+}
+
+#tracklist .header {
+    /* compensate for scrollbar. kind of icky. */
+    margin-right: 15px;
+    overflow: hidden;
+    
+    position: relative;
+    z-index: 1;
+}
+
+#tracklist .tracks {
+    position: absolute;
+    top: 18px;
+    left: 0;
+    right: 0;
+    bottom: 0;
+
+    overflow-x: hidden;
+    overflow-y: auto;
+}
+
+#tracklist .header &gt; *,
+#tracklist .row &gt; * {
+    display: block;
+    float: left;
+}
+
+#tracklist .header,
+#tracklist .row {
+    clear: left;
 }
 
+#tracklist .header,
+#tracklist .row,
+#tracklist .header &gt; *,
+#tracklist .row &gt; * {
+    height: 18px;
+    overflow: hidden;
+}
+
+#tracklist .icon         { width: 1% }
+#tracklist .name         { width: 29% }
+#tracklist .artist       { width: 29% }
+#tracklist .album        { width: 29% }
+#tracklist .time         { width: 5% }
+
 /* Styling */
 
 body {
@@ -36,8 +116,8 @@ a {
 }
 
 .selected {
-    background-color: #3d80df;
-    color: white;
+    background-color: #3d80df !important;
+    color: white !important;
 }
 
 /* Left pane */
@@ -48,40 +128,41 @@ a {
 }
 
 #sources li {
-    padding-left: 100em;
-    margin-left: -99em;
+    padding-left: 1em;
+}
+
+#sources li a {
+    display: block;
     
-    padding-top: 0.3em;
-    padding-bottom: 0.3em;
+    padding-left: 100em;
+    margin-left: -100em;
+
+    padding-top: 3px;
+    padding-bottom: 3px;
 }
 
 /* Right pane */
 
-#content th, #content td {
+#tracklist, #browser {
+    cursor: default;
+}
+
+#tracklist .header span, #tracklist .row span, #browser li {
     padding: 2px 4px;
 }
 
-#content th {
+#tracklist .header {
     border-bottom: 1px solid #555555;
 }
 
-#content td {
+#tracklist .row span {
     border-left: 1px solid #d9d9d9;
 }
 
-#content td:first-child {
+#tracklist .row span:first-child {
     border-left: none;
 }
 
-#content td.odd {
+#tracklist .row.odd {
     background: #f1f5fa;
 }
-
-#content tr.selected td {
-    background: none;
-}
-
-#content .name         { width: 29% }
-#content .artist       { width: 29% }
-#content .album        { width: 29% }
-#content .track_number { width: 9% }</diff>
      <filename>public/css/base.css</filename>
    </modified>
    <modified>
      <diff>@@ -1,39 +1,173 @@
-$(function() {
-    // alternating row colours
-    $('#content tr:odd td').addClass('odd');
-
-    // header gradient
-    // $('#content th').gradient({from: 'dbdbdb', to: 'bbbbbb'});
-    
-    // context menu
-    // $('tr').each(function() {
-    //     var ul = $(this).find('td.actions ul:first').attr('id', uniqueId());
-    //     var bindings = {}
-    //     
-    //     ul.find('li').each(function() {
-    //         $(this).attr('id', uniqueId());
-    //         bindings[$(this).attr('id')] = function() { console.log('hi!') };
-    //     });
-    //     
-    //     $(this).contextMenu(ul.attr('id'), {
-    //         onContextMenu: function() { console.log('hello') }
-    //     });
-    // });
-
-    $('.actions').hide();
-    
-    // select on click
-    $('#content tr').click(function() {
-        $('.selected').removeClass('selected');
-        $(this).addClass('selected');
-    });
-
-    // play on double-click
-    $('#content tr').dblclick(function() {
-        $.ajax({url: $(this).find('.action_play').attr('href')});
-    });
-    
-    function uniqueId() {
-        return 'uniqueId_' + new String(Math.random()).replace('0.', '');
+var Tracklist = {
+    focus: null,
+    
+    init: function() {
+        this.clearSelection();
+        
+        $('#tracklist')
+            .click(function(event) {
+                window.getSelection().removeAllRanges();
+                
+                var row = Tracklist.getClickedRow(event);
+            
+                if (!row) return;
+
+                if (event.metaKey) {
+                    Tracklist.toggleSelection(row);
+                } else if (event.shiftKey &amp;&amp; Tracklist.focus) {
+                    Tracklist.selectTo(row);
+                } else {
+                    Tracklist.setSelection(row);
+                }
+            })
+            .dblclick(function(event) {
+                window.getSelection().removeAllRanges();
+
+                if (Tracklist.selection.length == 0) {
+                    Tracklist.setSelection(Tracklist.getClickedRow(event));
+                }
+                
+                Tracklist.queueSelection();
+            })
+            .contextMenu('context_menu', {
+                bindings: {
+                    queue_selection: function() { Tracklist.queueSelection() },
+                    play_selection: function() { Tracklist.playSelection() }
+                },
+                
+                onShowMenu: function(event, menu) {
+                    var row = Tracklist.getClickedRow(event);
+                    
+                    if (!row.hasClass('selected')) {
+                        Tracklist.setSelection(row);
+                    }
+                    
+                    return menu;
+                }
+            });
+        
+        if ($('#browser').show().length &gt; 0) {
+            $('#browser').css('height', '50%');
+            $('#tracklist').css('top', '50%');
+            
+            var sourceId = window.location.pathname.match(/\d+$/)[0];
+            var artist = '', album = '';
+            
+            $('#artists').click(function(event) {
+                var li = $(event.target);
+
+                $(&quot;#artists, #albums&quot;).children().removeClass('selected');
+                li.addClass('selected');
+                
+                album = '';
+                artist = li.text();
+                if (artist == 'All') artist = '';
+                
+                filterTracklist();
+            });
+
+            $('#albums').click(function(event) {
+                var li = $(event.target);
+
+                $(this).children().removeClass('selected');
+                li.addClass('selected');
+
+                album = li.text();
+                if (album == 'All') album = '';
+                
+                filterTracklist();
+            });
+            
+            function filterTracklist() {
+                $.post(
+                    '/source/filter',
+
+                    {source_id: sourceId, artist: artist, album: album},
+
+                    function(data, textStatus) {
+                        var albumList = $('#albums', data);
+                        
+                        if (albumList.length &gt; 0) {
+                            $('#albums').html(albumList.html());
+                        }
+                        
+                        $('#tracklist').html($('#tracklist', data).html());
+                    });
+            }
+        }
+    },
+    
+    getClickedRow: function(event) {
+        return $(event.target).parents('.row');
+    },
+    
+    queueSelection: function() {
+        var selection = this.selection;
+        
+        $.post('/track/queue', this.selectionPaths(), function() {
+            selection.find('.icon').text('Q');
+        });
+    },
+
+    playSelection: function() {
+        var selection = this.selection;
+        
+        $.post('/track/play', this.selectionPaths(), function() {
+            selection.find('.icon').text('Q');
+        });
+    },
+    
+    selectionPaths: function() {
+        var paths = [];
+        
+        this.selection.each(function() {
+            paths.push($(this).attr('title'));
+        });
+        
+        return paths.join('\n');
+    },
+    
+    clearSelection: function() {
+        this.setSelection($('#NOTHING'));
+    },
+    
+    setSelection: function(e) {
+        if (this.selection) {
+            this.selection.removeClass('selected');
+        }
+        
+        this.selection = e.addClass('selected');
+        
+        if (this.selection.length == 1) {
+            this.focus = this.selection.get(0);
+        }
+    },
+    
+    toggleSelection: function(e) {
+        if (this.selection.index(e.get(0)) == -1) {
+            e.addClass('selected');
+            this.selection = this.selection.add(e);
+        } else {
+            e.removeClass('selected');
+            this.selection = this.selection.not(e);
+        }
+    },
+    
+    selectTo: function(e) {
+        e = e.eq(0);
+        
+        var pos = $(this.focus).nextAll().index(e.get(0));
+        
+        if (pos != -1) {
+            this.setSelection($(this.focus).nextAll(':lt(' + (pos+1) + ')').andSelf());
+        } else {
+            pos = e.nextAll().index(this.focus);
+            
+            if (pos != -1) {
+                Tracklist.setSelection(e.nextAll(':lt(' + (pos+1) + ')').andSelf());
+            }
+        }
     }
-});
+}
+
+$(function(){Tracklist.init()});</diff>
      <filename>public/js/base.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,22 @@
 require 'rubygems'
 require 'ramaze'
 
+# load RubyOSA
+require 'rbosa'
+OSA.utf8_strings = true
+
 # require all controllers and models
 acquire __DIR__/:controller/'*'
 acquire __DIR__/:model/'*'
 
+Itunes.get
+
+require 'ramaze/contrib/gzip_filter'
+Ramaze::Dispatcher::Action::FILTER &lt;&lt; Ramaze::Filter::Gzip
+
+Ramaze::Dispatcher::Action::FILTER &lt;&lt; proc { |response|
+  response['content-type'] = 'text/html; charset=utf-8'
+  response
+}
+
 Ramaze.start :adapter =&gt; :webrick, :port =&gt; 7000</diff>
      <filename>start.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,8 +7,6 @@
     &lt;link rel=&quot;stylesheet&quot; href=&quot;/css/base.css&quot; type=&quot;text/css&quot; /&gt;
 
     &lt;script src=&quot;/js/jquery.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;/js/jquery.dimensions.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
-    &lt;script src=&quot;/js/jquery.gradient.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
     &lt;script src=&quot;/js/jquery.contextmenu.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
     &lt;script src=&quot;/js/base.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
 &lt;/head&gt;
@@ -16,18 +14,20 @@
 &lt;body&gt;
     &lt;div id=&quot;sources&quot;&gt;
         &lt;ul&gt;
-            &lt;?r Itunes.get.sources.values.sort.each do |source|
-                li_class = (@source == source and !@playlist) ? 'selected' : ''
-            ?&gt;
-                &lt;li class=&quot;#{li_class}&quot;&gt;
-                    &lt;p&gt;#{A source.name, :href =&gt; R(SourceController, :list, source.id2)}&lt;/p&gt;
+            &lt;li&gt;
+                #{highlighted_link 'Jukebox', R(JukeboxController)}
+            &lt;/li&gt;
+            
+            &lt;?r Itunes.get.sources.each do |source| ?&gt;
+                &lt;li&gt;
+                    #{highlighted_link source.name, R(SourceController, :list, source.id2)}
 
                     &lt;ul&gt;
-                        &lt;?r source.playlists.values.sort.each do |playlist|
-                            li_class = (@playlist == playlist) ? 'selected' : ''
+                        &lt;?r source.playlists.each do |playlist|
+                            next if playlist.name == source.library_playlist.name
                         ?&gt;
-                            &lt;li class=&quot;#{li_class}&quot;&gt;
-                                #{A playlist.name, :href =&gt; R(PlaylistController, :list, source.id2, playlist.id2)}
+                            &lt;li&gt;
+                                #{highlighted_link playlist.name, R(PlaylistController, :list, source.id2, playlist.id2)}
                             &lt;/li&gt;
                         &lt;?r end ?&gt;
                     &lt;/ul&gt;</diff>
      <filename>view/app.xhtml</filename>
    </modified>
    <modified>
      <diff>@@ -1,25 +1,2 @@
-&lt;table&gt;
-    &lt;tr&gt;
-        &lt;th class=&quot;name&quot;&gt;Name&lt;/th&gt;
-        &lt;th class=&quot;artist&quot;&gt;Artist&lt;/th&gt;
-        &lt;th class=&quot;album&quot;&gt;Album&lt;/th&gt;
-        &lt;th class=&quot;track_number&quot;&gt;Track \#&lt;/th&gt;
-    &lt;/tr&gt;
-    
-    &lt;?r @playlist.tracks.each do |track| ?&gt;
-        &lt;tr&gt;
-            &lt;td class=&quot;name&quot;&gt;#{track.name}&lt;/td&gt;
-            &lt;td class=&quot;artist&quot;&gt;#{track.artist}&lt;/td&gt;
-            &lt;td class=&quot;album&quot;&gt;#{track.album}&lt;/td&gt;
-            &lt;td class=&quot;track_number&quot;&gt;#{track.track_number}&lt;/td&gt;
-            
-            &lt;td class=&quot;actions&quot;&gt;
-                &lt;ul&gt;
-                    &lt;li&gt;
-                        #{A('Play', :class =&gt; 'action_play', :href =&gt; href = R(TrackController, :play, @source.id2, @playlist.id2, track.id2))}
-                    &lt;/li&gt;
-                &lt;/li&gt;
-            &lt;/td&gt;
-        &lt;/tr&gt;
-    &lt;?r end ?&gt;
-&lt;/table&gt;
\ No newline at end of file
+#{render_template '../tracklist'}
+#{render_template '../context_menu'}</diff>
      <filename>view/playlist/list.xhtml</filename>
    </modified>
    <modified>
      <diff>@@ -1,25 +1,3 @@
-&lt;table&gt;
-    &lt;tr&gt;
-        &lt;th class=&quot;name&quot;&gt;Name&lt;/th&gt;
-        &lt;th class=&quot;artist&quot;&gt;Artist&lt;/th&gt;
-        &lt;th class=&quot;album&quot;&gt;Album&lt;/th&gt;
-        &lt;th class=&quot;track_number&quot;&gt;Track \#&lt;/th&gt;
-    &lt;/tr&gt;
-    
-    &lt;?r @playlist.tracks.each do |track| ?&gt;
-        &lt;tr&gt;
-            &lt;td class=&quot;name&quot;&gt;#{track.name}&lt;/td&gt;
-            &lt;td class=&quot;artist&quot;&gt;#{track.artist}&lt;/td&gt;
-            &lt;td class=&quot;album&quot;&gt;#{track.album}&lt;/td&gt;
-            &lt;td class=&quot;track_number&quot;&gt;#{track.track_number}&lt;/td&gt;
-            
-            &lt;td class=&quot;actions&quot;&gt;
-                &lt;ul&gt;
-                    &lt;li&gt;
-                        #{A('Play', :class =&gt; 'action_play', :href =&gt; href = R(TrackController, :play, @source.id2, @playlist.id2, track.id2))}
-                    &lt;/li&gt;
-                &lt;/li&gt;
-            &lt;/td&gt;
-        &lt;/tr&gt;
-    &lt;?r end ?&gt;
-&lt;/table&gt;
\ No newline at end of file
+#{render_template '../browser'}
+#{render_template '../tracklist'}
+#{render_template '../context_menu'}</diff>
      <filename>view/source/list.xhtml</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a2b8b44489322d37681fc230242f3c27de61b8b3</id>
    </parent>
  </parents>
  <author>
    <name>Aanand Prasad</name>
    <email>aanand.prasad@gmail.com</email>
  </author>
  <url>http://github.com/aanand/itunes-web-interface/commit/8716f0a96889cdc7e7aaee1a2bd11979b575475c</url>
  <id>8716f0a96889cdc7e7aaee1a2bd11979b575475c</id>
  <committed-date>2008-04-19T10:57:22-07:00</committed-date>
  <authored-date>2008-04-19T10:57:22-07:00</authored-date>
  <message>A bunch of stuff. I'm not being organised about this.</message>
  <tree>1b2629717d5b77cac457c64146d2fd8239c7285f</tree>
  <committer>
    <name>Aanand Prasad</name>
    <email>aanand.prasad@gmail.com</email>
  </committer>
</commit>
