<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/adapters/fs.rb</filename>
    </added>
    <added>
      <filename>lib/adapters/s3.rb</filename>
    </added>
    <added>
      <filename>spec/fads_fs_dir_spec.rb</filename>
    </added>
    <added>
      <filename>spec/fads_fs_file_spec.rb</filename>
    </added>
    <added>
      <filename>spec/fads_fs_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,61 @@
-module FSDS::Dir
+class FSDS::FS::Dir &lt; FSDS::FS
+  # Retuns a FSDS::FS::Dir (Directory Object).  The path, permissions, ownership &amp; group can be 
+  # specified as attributes. The filesystem is not touched by this method.  The methods that 
+  # make changes to the filesystem are generally ending with an exclamation point (!) and the 
+  # methods that read from the filesystem are generally ending with a question mark (?).
+  #
+  # See also :mkdir
+  #
+  # Examples:
+  #   FSDS::FS::Dir.new '/tmp/test'
+  #   FSDS::FS::Dir.new '/tmp/test', 755
+  #   FSDS::FS::Dir.new '/tmp/test', 755, 'joshaven'
+  #   FSDS::FS::Dir.new '/tmp/test', 755, 'joshaven', 'staff'
+  #   FSDS::FS::Dir.new '/tmp/test', nil, 'joshaven'     # The attributes are ordered, however they are ignored if nil.
+  def initialize(*args)
+    super *args
+    self.type = FSDS::FS::Dir if type.nil?
+  end
+  
+  # Create a file or directory on the filesystem if it doesn't already exist and set permissions, owner,
+  # &amp; group if specified. See FSDS::new for full param options.  They type paramter is required and must be 
+  # one of: [:file, :dir].  Returns an FSDS instance.  See also the shortcut methods: :mkdir &amp; :touch
+  #
+  #
+  # Examples:
+  #   p=FSDS.new  '/tmp/deleteme'         # This assumes that you have set: FSDS::default_type = FSDS::FS
+  #   p.create! :file                     # Returns an instance of: FSDS::FS::File
+  #
+  #   # The same can be done in one line: # Also assumes that you've set: FSDS::default_type = FSDS::FS
+  #   FSDS.create! :file, '/tmp/deleteme'
+  #
+  #   # If you need root access then send it a sudo:
+  #   FSDS.create! :file, '/etc/deleteme', {:sudo =&gt; 'superSecretPassword'}
+  def create!(pth=path, options={})
+    options, pth = pth, options if Hash === pth   # Swap arguments if arguments are backwards
+    pth = path if Hash === pth
+    
+    return false unless String === pth            # validate arg
+    path = pth                                    # ensure the path is set
+    
+    cmd_prefix = options.has_key?(:sudo) ? &quot;echo #{options[:sudo]}| sudo -S &quot; : ''
+    
+    begin
+      raise(&quot;Could not make dir: #{path}&quot;) unless system_to_boolean(&quot;#{cmd_prefix} mkdir #{options[:arguments]} #{path}&quot;)
+      # TODO: I think this needs to revert to the above method, need to test making a dir that requires sudo
+      # ::Dir::mkdir(path)
+    rescue
+      raise FSDS::IOError
+    end unless ::File.directory? path
+    
+    # sudo_options = options.has_key?(:sudo) ? {:sudo =&gt; options[:sudo]} : {}
+    owner! sudo_options
+    group! sudo_options
+    permissions! sudo_options
+    
+    return self
+  end
+  alias_method :mkdir, :create!
+
   
 end
\ No newline at end of file</diff>
      <filename>lib/adapters/fs/dir.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,20 +1,164 @@
-module FSDS::File
-  def greet
-    &quot;Hello from FSDS::File&quot;
+class FSDS::FS::File &lt; FSDS::FS
+  def initialize(*args)
+    super *args
+    self.type = FSDS::FS::File if type.nil?
   end
-  
-  
-  # # This breaks out of the FSDS wrapper and allows access to the standard objects: File, Dir
-  # def method_missing(mth, *args)
-  #   # this assumes that a path is the standard input... this is not very protected... need to check Dile &amp; Dir API's
-  #   args = [path] if args.empty?
-  #   
-  #   my_type = self.type
-  #   if my_type == File
-  #     ::File.send(mth, *args) if File.methods.include? mth.to_s
-  #   elsif my_type == Dir
-  #     ::Dir.send(mth, *args) if Dir.methods.include? mth.to_s
+
+  # Return or set the type of the FSDS.  The answer will be one of: the adapter types, or nil
+  # def type(klass = nil)
+  #   if klass.nil?
+  #     @type = ::File.file?(path || '') ? File : (::File.directory?(path || '') ? Dir : nil)
+  #   elsif Class === klass.class
+  #     @type = klass
+  #   else
+  #     nil
   #   end
-  #   
   # end
-end
\ No newline at end of file
+  
+  # Create a file or directory on the filesystem if it doesn't already exist and set permissions, owner,
+  # &amp; group if specified. See FSDS::new for full param options.  They type paramter is required and must be 
+  # one of: [:file, :dir].  Returns an FSDS instance.  See also the shortcut methods: :mkdir &amp; :touch
+  #
+  #
+  # Examples:
+  #   p=FSDS.new  '/tmp/deleteme'         # This assumes that you have set: FSDS::default_type = FSDS::FS
+  #   p.create! :file                     # Returns an instance of: FSDS::FS::File
+  #
+  #   # The same can be done in one line: # Also assumes that you've set: FSDS::default_type = FSDS::FS
+  #   FSDS.create! :file, '/tmp/deleteme'
+  #
+  #   # If you need root access then send it a sudo:
+  #   FSDS.create! :file, '/etc/deleteme', {:sudo =&gt; 'superSecretPassword'}
+  def create!(pth=path, options={})
+    #####
+    # Need to write this lines support code:
+    #   pth,options = sort_path_and_options(pth, options)
+    #####
+    # from:
+    options, pth = pth, options if Hash === pth   # Swap arguments if arguments are backwards
+    pth = path if Hash === pth
+    return false unless String === pth            # validate arg
+    path = pth                                    # ensure the path is set
+    #####
+    
+    cmd_prefix = options.has_key?(:sudo) ? &quot;echo #{options[:sudo]}| sudo -S &quot; : ''
+    my_type = self.type  # minimize access to File.file? &amp; File.directory?
+    
+    # # Depreciate system call to touch in favor of writing nothing to the file through :concat!
+    # raise(&quot;Could not touch file: #{path}&quot;) unless system_to_boolean(&quot;#{cmd_prefix} touch #{options[:arguments]} #{path}&quot;)
+    self.concat! ''
+    
+    # sudo_options = options.has_key?(:sudo) ? {:sudo =&gt; options[:sudo]} : {}
+    owner! sudo_options
+    group! sudo_options
+    permissions! sudo_options
+    
+    return self
+  end
+  alias_method :touch, :create!
+  
+  # Returns true or false.  Shortcut method to: FSDS.new('/tmp').type != nil
+  #
+  # Examples:
+  #   FSDS.exists?(&quot;/tmp&quot;)           #=&gt; true
+  def exists?
+    ::File.file? path
+  end
+  
+  
+  # Removes FSDS from filesystem, returning true if successful or false if unsuccessful.
+  #
+  # Options:
+  # * options may contain a hash with a sudo key containing a password: p.destroy!({:sudo =&gt; 'superSecret'})
+  #
+  # Example:
+  # p = FSDS.touch('/tmp/deleteme')
+  # p.destroy!                          # =&gt; true
+  # p.destroy!                          # =&gt; false    # its already gone, but the FSDS object remains.
+  # p.destroy! :sudo =&gt; 'superSecret'   # =&gt; false    # This does delete as super user, but its still not there
+  # FSDS.destroy!('/tmp/not_here_123')  # =&gt; false    # This assumes that you have set FSDS::default_type
+  def destroy!(options={})
+    begin
+      if options.has_key? :sudo
+        system_to_boolean &quot;echo #{options[:sudo]}| sudo -S rm #{path}&quot;
+      else
+        system_to_boolean &quot;rm #{path}&quot;
+      end
+    rescue
+      false
+    end
+  end
+  
+  # Appends to a file or raises FSDS::IOError.  This method does not do anything with new line characters.  If you
+  # want to write a line of text see the :writeln method.  This method will railse FSDS::IOError if fild doesn't exist
+  # call :concat! to create the file by writing to it.
+  #
+  # Example:
+  #   f = FSDS::FS.touch '/tmp/deleteme'
+  #   f &lt;&lt; 'Hello'
+  #   f.concat 'World'
+  #   f.read                    #=&gt; &quot;HelloWorld&quot;
+  def concat(data)
+    raise FSDS::IOError unless exists?
+    concat! data
+  end
+  def concat!(data)
+    begin
+      ::File.open(path, 'a') { |f| f.print data }
+      self
+    rescue
+      raise FSDS::IOError
+    end
+  end
+  alias_method :&lt;&lt;, :concat
+  
+  # Writes a string with an appended newline to to a file.    
+  #
+  # Example:
+  #   f = FSDS.new 'path/to/file'
+  #   f.read   #=&gt; &quot;Line: 0\nLine: 1\n&quot;
+  #
+  # FIXME:  should be sure prior char is a newline or prepend a newline &amp; end with a newline
+  def writeln(data)
+    concat &quot;#{data.chomp}\n&quot;
+  end
+
+  # Returns the entire file as a string.
+  #
+  # Example:
+  #   f = FSDS.new 'path/to/file'
+  #   f.read   #=&gt; &quot;Line: 0\nLine: 1\n&quot;
+  def read
+    ::File.read(path) # documented in IO class
+  end
+
+  # Returns a line as a String or a range of lines as an Array.  Given a 10 line file, the first line would be 0 and 
+  # the last line would be 9. Represented as a range this would be: file.readln(0..9)
+  # 
+  # Examples:
+  #   f = FSDS.new 'path/to/file'
+  #   f.readln 0   #=&gt; &quot;Line: 0&quot;
+  #   f.readln(0..2)   #=&gt; [&quot;Line: 0&quot;, &quot;Line: 1&quot;, &quot;Line: 2&quot;]
+  def readln(line)
+    if Fixnum === line
+      str = ::File.readlines(path)[line]
+      String === str ? str.chomp : str
+    elsif Range === line
+      ::File.readlines(path)[line.first, line.last+1].collect {|str| str.chomp if String === str}
+    end
+  end
+end
+
+# # This breaks out of the FSDS wrapper and allows access to the standard objects: File, Dir
+# def method_missing(mth, *args)
+#   # this assumes that a path is the standard input... this is not very protected... need to check Dile &amp; Dir API's
+#   args = [path] if args.empty?
+#   
+#   my_type = self.type
+#   if my_type == File
+#     ::File.send(mth, *args) if File.methods.include? mth.to_s
+#   elsif my_type == Dir
+#     ::Dir.send(mth, *args) if Dir.methods.include? mth.to_s
+#   end
+#   
+# end
\ No newline at end of file</diff>
      <filename>lib/adapters/fs/file.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,15 @@
 class FSDS
-  # require 'adapters/fs/file'
+  # Require all adapters  requireing any: ./lib/adapters/#{adapter_name}/#{adapter_name}.rb
+  # ::Dir.glob('lib/adapters/*.rb').each {|adapter_file| require adapter_file }
+  Dir.glob(File.expand_path(File.dirname(__FILE__))+'/adapters/*.rb').each {|adapter_file| require adapter_file }
   
   FSDS::IOError = &quot;IOError: Cannot communicate with file.&quot;
+
+#^^^^^^^^^^^^^^^ Above this line stays
+
+
+
+
   attr_accessor :path, :permissions, :owner, :group
   # Retuns a FSDS (File System Object).  The path, permissions, ownership &amp; group can be 
   # specified as attributes. The filesystem is not touched by this method.  The methods that 
@@ -21,12 +29,15 @@ class FSDS
     self.group       = grp unless grp.nil?
   end
 
-  # Return the type of the FSDS.  The answer will be one of: File, Dir, or nil
-  def type
-    # return File if File.file?(path || '')
-    # return Dir if File.directory?(path || '')
-    # nil
-    File.file?(path || '') ? File : (File.directory?(path || '') ? Dir : nil)
+  # Return or set the type of the FSDS.  The answer will be one of: the adapter types, or nil
+  def type(klass = nil)
+    if klass.nil?
+      @type = File.file?(path || '') ? File : (File.directory?(path || '') ? Dir : nil)
+    elsif Class === klass.class
+      @type = klass
+    else
+      nil
+    end
   end
 
   # Shortcut method to finding the type of a filesystem object without instantizing an FSDS.
@@ -366,6 +377,7 @@ class FSDS
     end
   end
 
+  
   def to_s
     path
   end
@@ -402,6 +414,9 @@ private
   end
 end
 
+#&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; Beginning of RemoveMe
+#&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; End of RemoveMe
+
 
 
 # make the :new method optional...  appends the Kernel object.</diff>
      <filename>lib/fsds.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,224 +1,223 @@
-require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-
-describe 'FSDS' do
-  before :all do
-    # Enable the following and set your password to test things that require sudo
-    # @sudo_passwd = 'SuperSecret'
-    @test_path = '/tmp/deleteme'
-  end
-
-  before :each do
-    FSDS.destroy! @test_path
-  end
-  
-  # it 'Reminder to remove sudo password from setup block' {pending{fail}}
-  
-  it 'should instantize' do
-    FSDS.new('/tmp').should === Dir
-    FSDS('/tmp').should === Dir  # Wow, nice loverly thing!
-                                # Thanks to the ability to extend the Kernel without a conflict in naming with constants!
-  end
-  
-  it 'should answer exists?' do
-    # test dir
-    FSDS.exists?('/tmp/').should be_true
-    FSDS.exists?('/tmp/not/here/ever/12345678900987654321/').should be_false
-    FSDS.new('/tmp').exists?.should be_true
-    FSDS.new('/tmp/not/here/ever/12345678900987654321/').exists?.should be_false
-    # test file
-    FSDS.touch @test_path
-    FSDS.exists?(@test_path).should be_true
-  end
-  
-  it 'should handle :mkdir and :destroy for files or folders' do
-    FSDS.exists?(@test_path).should be_false
-    p = FSDS.mkdir @test_path   # creates a dir
-    p.exists?.should be_true
-    FSDS.mkdir(@test_path).should be_true   # dir already exists so mkdir is true
-    p.destroy!
-    p.exists?.should be_false
-  end
-  
-  it 'should handle :touch' do
-    f = FSDS.touch @test_path
-    f.should === File
-    FSDS.touch(@test_path).should be_true  # You should be able to touch existing files...
-    f.destroy!
-    
-    d = FSDS.mkdir @test_path
-    FSDS.touch(@test_path).should be_false
-  end
-  
-  it &quot;should respond to proprieties&quot; do
-    # for dir
-    d = FSDS.new '/tmp'
-    d.proprieties[:group].should =~ /wheel|root/
-    # for file
-    f = FSDS.touch @test_path
-    f.proprieties[:group].should =~ /wheel|root/
-  end
-  
-  it 'should handle :permissions permissions? permissions!' do
-    passwd = FSDS.new('/etc/passwd')
-    passwd.permissions?.should === 644
-    
-    # for dir
-    d = FSDS.new '/tmp'
-    d.permissions.should be_nil
-    d.permissions?.should === 755
-    Integer.should === d.permissions?
-    d = FSDS.new '/tmp/not_real/'
-    d.permissions?.should be_nil
-    
-    # set permissions
-    d=FSDS.new('~/delete_me_dir')
-    d.destroy!
-    d.mkdir
-    d.permissions?.should === 755
-    d.permissions!(777).should be_true
-    d.permissions?.should === 777
-    d.destroy!
-    d.mkdir
-    d.permissions!({:arguments =&gt; '-R'}, 777).should be_true  # test swapped attributes
-    d.permissions?.should === 777
-    d.destroy!
-    
-    # for file
-    f=FSDS.touch '~/deleteme'
-    Integer.should === f.permissions?
-    f.permissions?.should_not == 777
-    f.permissions!(777).should be_true
-    f.permissions?.should == 777
-    f.destroy!
-  end
-  
-  it 'should handle :owner, :owner?, &amp; :owner!' do
-    # for dir
-    my_user_name = `whoami`.chomp
-
-    d = FSDS.new @test_path
-    d.destroy!
-    d.owner?.should be_nil
-    d.mkdir
-    d.owner?.should == my_user_name
-    new_owner = my_user_name
-    d.owner new_owner
-    d.owner!.should be_true
-    d.destroy!.should be_true
-    d.destroy!.should be_false
-    if @sudo_passwd
-      d.mkdir
-      new_owner = 'root'
-      d.owner new_owner
-      d.owner.should == new_owner
-      d.owner?.should == my_user_name
-      d.owner!( :sudo =&gt; @sudo_passwd ).should be_true
-      d.owner?.should == new_owner
-      d.destroy! :sudo =&gt; @sudo_passwd
-      d.owner!.should be_false
-    end
-    
-    # for file
-    f = FSDS.touch @test_path
-    f.owner?.should == my_user_name
-    f.destroy!
-    if @sudo_password
-      f.touch
-      f.owner!('root', {:sudo=&gt; @sudo_password}).should be_true
-      f.owner?.should == 'root'
-      f.destroy!({:sudo=&gt; @sudo_password}).should be_true
-    end
-  end
-  
-  it &quot;should handle :group, :group?, &amp; :group!&quot; do
-    # for dir
-    d = FSDS.new @test_path
-    d.destroy! # Ensure we have a clean slate!
-    d.mkdir
-    d.group.should be_nil
-    d.group?.should =~ /wheel|root/
-    d.group! 'staff'
-    d.group?.should == 'staff'
-    # the following cannot be done without superuser, but it works when provided a password
-    if @sudo_passwd
-      d.group = FSDS.group?('/tmp')
-      d.group!('everyone', {:sudo =&gt; @sudo_passwd}).should be_true
-      d.group?.should == 'everyone'
-    end
-    d.destroy!.should be_true
-    
-    # for File
-    f = FSDS.new @test_path
-    f.destroy!
-    f.touch
-    f.group?.should =~ /wheel|root/
-    
-    f.group!('everyone').should be_true
-    f.group?.should == 'everyone'
-  end
-  
-  it 'should inherit permissions' do
-    d = FSDS.mkdir '/tmp/deleteme/'
-    d.group?.should == FSDS.group?('/tmp')
-    d.destroy!
-    
-    f = FSDS.touch @test_path
-    f.group?.should == FSDS.group?('/tmp')
-  end
-  
-  it 'should know to_s' do
-    p=FSDS.new @test_path
-    p.to_s.should == @test_path
-  end  
-  
-  it 'should be able to pass missing methods to the file &amp; dir objects' do
-    f = FSDS.touch @test_path
-    f.executable?.should == false  # should turn into:  File.executable?(file_name) =&gt; true or false
-    pending do  
-      # need to double check the method_missing instance method of FSDS... some asumptions are being made
-      fail
-    end
-  end
-  
-  it 'should be able to read &amp; write files' do
-    f = FSDS.touch @test_path
-    f.concat 'First'
-    f &lt;&lt; ' test!'
-    f.read.should == &quot;First test!&quot;
-    f &lt;&lt; &quot;\nSecond line.&quot;
-    f.read.should == &quot;First test!\nSecond line.&quot;
-  end
-  
-  it 'should return self when writing to a file or raise an error' do
-    lambda { FSDS(@test_path) &lt;&lt; 'hello' }.should raise_error(FSDS::IOError)
-  end
-  
-  it 'should write by line' do
-    f = FSDS.touch @test_path
-    f.writeln &quot;First&quot;
-    f.writeln(&quot;Second&quot;).should be_true
-    f.read.should == &quot;First\nSecond\n&quot;
-  end
-  
-  it 'should read lines by number' do
-    f = FSDS.touch @test_path
-    (0..4).to_a.each {|i| f.writeln &quot;Line: #{i}&quot;}
-    f.readln(0).should == &quot;Line: 0&quot;
-    f.readln(4).should == &quot;Line: 4&quot;
-    # There are only lines 0 through 4... line 5 is non-existant and so returns nil.
-    f.readln(5).should be_nil
-  end
-  
-  it 'should read lines by range' do
-    f = FSDS.touch @test_path
-    (0..3).to_a.each {|i| f.writeln &quot;Line: #{i}&quot;}
-    f.readln((0..2)).should == [&quot;Line: 0&quot;, &quot;Line: 1&quot;, &quot;Line: 2&quot;]
-    # Should not go beyond the limits of the file... the following is equal to read: 
-    #   beginning at the third line through the next hundred lines...
-    f.readln((2..100)).should == [&quot;Line: 2&quot;, &quot;Line: 3&quot;]
-  end
-  
-  # it 'should have a FSDS::File class' do
-  #   FSDS::File.greet.should == &quot;Hello from FSDS::File&quot;
-  # end
-end
+# require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+# 
+# describe 'FSDS' do
+#   before :all do
+#     # Enable the following and set your password to test things that require sudo
+#     # @sudo_passwd = 'SuperSecret'
+#     @test_path = '/tmp/deleteme'
+#   end
+# 
+#   before :each do
+#     FSDS.destroy! @test_path
+#   end
+#   
+#   # it 'Reminder to remove sudo password from setup block' {pending{fail}}
+#   
+#   # FIXME:  FSDS::FS.exists?  should figure out what type of FS object it is
+#   #         and answer using that objects method... through :method_missing
+#   
+#   it 'should instantize' do
+#     FSDS.new('/tmp').should === Dir
+#     FSDS('/tmp').should === Dir     # Wow, nice loverly thing!
+#                                     # Thanks to the ability to extend the Kernel without a conflict in naming with constants!
+#   end
+#   
+#   it 'should answer exists?' do
+#     # test dir
+#     FSDS.exists?('/tmp/').should be_true
+#     FSDS.exists?('/tmp/not/here/ever/12345678900987654321/').should be_false
+#     FSDS.new('/tmp').exists?.should be_true
+#     FSDS.new('/tmp/not/here/ever/12345678900987654321/').exists?.should be_false
+#     # test file
+#     FSDS.touch @test_path
+#     FSDS.exists?(@test_path).should be_true
+#   end
+#   
+#   it 'should handle :mkdir and :destroy for files or folders' do
+#     FSDS.exists?(@test_path).should be_false
+#     p = FSDS.mkdir @test_path   # creates a dir
+#     p.exists?.should be_true
+#     FSDS.mkdir(@test_path).should be_true   # dir already exists so mkdir is true
+#     p.destroy!
+#     p.exists?.should be_false
+#   end
+#   
+#   it 'should handle :touch' do
+#     f = FSDS.touch @test_path
+#     f.should === File
+#     FSDS.touch(@test_path).should be_true  # You should be able to touch existing files...
+#     f.destroy!
+#     
+#     d = FSDS.mkdir @test_path
+#     FSDS.touch(@test_path).should be_false
+#   end
+#   
+#   it &quot;should respond to proprieties&quot; do
+#     # for dir
+#     d = FSDS.new '/tmp'
+#     d.proprieties[:group].should =~ /wheel|root/
+#     # for file
+#     f = FSDS.touch @test_path
+#     f.proprieties[:group].should =~ /wheel|root/
+#   end
+#   
+#   it 'should handle :permissions permissions? permissions!' do
+#     passwd = FSDS.new('/etc/passwd')
+#     passwd.permissions?.should === 644
+#     
+#     # for dir
+#     d = FSDS.new '/tmp'
+#     d.permissions.should be_nil
+#     d.permissions?.should === 755
+#     Integer.should === d.permissions?
+#     d = FSDS.new '/tmp/not_real/'
+#     d.permissions?.should be_nil
+#     
+#     # set permissions
+#     d=FSDS.new('~/delete_me_dir')
+#     d.destroy!
+#     d.mkdir
+#     d.permissions?.should === 755
+#     d.permissions!(777).should be_true
+#     d.permissions?.should === 777
+#     d.destroy!
+#     d.mkdir
+#     d.permissions!({:arguments =&gt; '-R'}, 777).should be_true  # test swapped attributes
+#     d.permissions?.should === 777
+#     d.destroy!
+#     
+#     # for file
+#     f=FSDS.touch '~/deleteme'
+#     Integer.should === f.permissions?
+#     f.permissions?.should_not == 777
+#     f.permissions!(777).should be_true
+#     f.permissions?.should == 777
+#     f.destroy!
+#   end
+#   
+#   it 'should handle :owner, :owner?, &amp; :owner!' do
+#     # for dir
+#     my_user_name = `whoami`.chomp
+# 
+#     d = FSDS.new @test_path
+#     d.destroy!
+#     d.owner?.should be_nil
+#     d.mkdir
+#     d.owner?.should == my_user_name
+#     new_owner = my_user_name
+#     d.owner new_owner
+#     d.owner!.should be_true
+#     d.destroy!.should be_true
+#     d.destroy!.should be_false
+#     if @sudo_passwd
+#       d.mkdir
+#       new_owner = 'root'
+#       d.owner new_owner
+#       d.owner.should == new_owner
+#       d.owner?.should == my_user_name
+#       d.owner!( :sudo =&gt; @sudo_passwd ).should be_true
+#       d.owner?.should == new_owner
+#       d.destroy! :sudo =&gt; @sudo_passwd
+#       d.owner!.should be_false
+#     end
+#     
+#     # for file
+#     f = FSDS.touch @test_path
+#     f.owner?.should == my_user_name
+#     f.destroy!
+#     if @sudo_password
+#       f.touch
+#       f.owner!('root', {:sudo=&gt; @sudo_password}).should be_true
+#       f.owner?.should == 'root'
+#       f.destroy!({:sudo=&gt; @sudo_password}).should be_true
+#     end
+#   end
+#   
+#   it &quot;should handle :group, :group?, &amp; :group!&quot; do
+#     # for dir
+#     d = FSDS.new @test_path
+#     d.destroy! # Ensure we have a clean slate!
+#     d.mkdir
+#     d.group.should be_nil
+#     d.group?.should =~ /wheel|root/
+#     d.group! 'staff'
+#     d.group?.should == 'staff'
+#     # the following cannot be done without superuser, but it works when provided a password
+#     if @sudo_passwd
+#       d.group = FSDS.group?('/tmp')
+#       d.group!('everyone', {:sudo =&gt; @sudo_passwd}).should be_true
+#       d.group?.should == 'everyone'
+#     end
+#     d.destroy!.should be_true
+#     
+#     # for file
+#     f = FSDS.new @test_path
+#     f.destroy!
+#     f.touch
+#     f.group?.should =~ /wheel|root/
+#     
+#     f.group!('everyone').should be_true
+#     f.group?.should == 'everyone'
+#   end
+#   
+#   it 'should inherit permissions' do
+#     d = FSDS.mkdir '/tmp/deleteme/'
+#     d.group?.should == FSDS.group?('/tmp')
+#     d.destroy!
+#     
+#     f = FSDS.touch @test_path
+#     f.group?.should == FSDS.group?('/tmp')
+#   end
+#   
+#   it 'should know to_s' do
+#     p=FSDS.new @test_path
+#     p.to_s.should == @test_path
+#   end  
+#   
+#   it 'should be able to read &amp; write files' do
+#     f = FSDS.touch @test_path
+#     f.concat 'First'
+#     f &lt;&lt; ' test!'
+#     f.read.should == &quot;First test!&quot;
+#     f &lt;&lt; &quot;\nSecond line.&quot;
+#     f.read.should == &quot;First test!\nSecond line.&quot;
+#   end
+#   
+#   it 'should return self when writing to a file or raise an error' do
+#     lambda { FSDS(@test_path) &lt;&lt; 'hello' }.should raise_error(FSDS::IOError)
+#   end
+#   
+#   it 'should write by line' do
+#     f = FSDS.touch @test_path
+#     f.writeln &quot;First&quot;
+#     f.writeln(&quot;Second&quot;).should be_true
+#     f.read.should == &quot;First\nSecond\n&quot;
+#   end
+#   
+#   it 'should read lines by number' do
+#     f = FSDS.touch @test_path
+#     (0..4).to_a.each {|i| f.writeln &quot;Line: #{i}&quot;}
+#     f.readln(0).should == &quot;Line: 0&quot;
+#     f.readln(4).should == &quot;Line: 4&quot;
+#     # There are only lines 0 through 4... line 5 is non-existant and so returns nil.
+#     f.readln(5).should be_nil
+#   end
+#   
+#   it 'should read lines by range' do
+#     f = FSDS.touch @test_path
+#     (0..3).to_a.each {|i| f.writeln &quot;Line: #{i}&quot;}
+#     f.readln((0..2)).should == [&quot;Line: 0&quot;, &quot;Line: 1&quot;, &quot;Line: 2&quot;]
+#     # Should not go beyond the limits of the file... the following is equal to read: 
+#     #   beginning at the third line through the next hundred lines...
+#     f.readln((2..100)).should == [&quot;Line: 2&quot;, &quot;Line: 3&quot;]
+#   end
+#   
+#   it 'should be able to pass missing methods to the file &amp; dir objects' do
+#     f = FSDS.touch @test_path
+#     f.executable?.should == false  # should accessed proxied object
+#     pending do  
+#       # need to double check the method_missing instance method of FSDS... some asumptions are being made
+#       fail
+#     end
+#   end
+# end</diff>
      <filename>spec/fads_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>64081cd86c021dfeacbd83ac86516f6b6857aa56</id>
    </parent>
  </parents>
  <author>
    <name>Joshaven Potter</name>
    <email>yourtech@gmail.com</email>
  </author>
  <url>http://github.com/joshaven/fsds/commit/9cbdd5514d31055f4ddc8574d6a982641c949969</url>
  <id>9cbdd5514d31055f4ddc8574d6a982641c949969</id>
  <committed-date>2009-10-23T15:39:19-07:00</committed-date>
  <authored-date>2009-10-23T15:39:19-07:00</authored-date>
  <message>Migrate File proxy object to FSDS::FS::File class &amp; move tests;
Begin migration of Dir proxy object.</message>
  <tree>361fdf3d717b70f2cda472a31c09cfdc8a8dd965</tree>
  <committer>
    <name>Joshaven Potter</name>
    <email>yourtech@gmail.com</email>
  </committer>
</commit>
