diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb
index cfc15669ffa566c24bc383e2b76f78c34e993799..9ea9ac48e23ae98298191d1b7fe79b6f93e61f52 100644
--- a/app/controllers/attachments_controller.rb
+++ b/app/controllers/attachments_controller.rb
@@ -23,7 +23,10 @@ class AttachmentsController < ApplicationController
     if @attachment.is_diff?
       @diff = File.new(@attachment.diskfile, "rb").read
       render :action => 'diff'
-    else
+    elsif @attachment.is_text?
+      @content = File.new(@attachment.diskfile, "rb").read
+      render :action => 'file'
+    elsif
       download
     end
   end
@@ -38,9 +41,9 @@ class AttachmentsController < ApplicationController
 private
   def find_project
     @attachment = Attachment.find(params[:id])
-    render_404 and return false unless File.readable?(@attachment.diskfile)
+    #render_404 and return false unless File.readable?(@attachment.diskfile)
     @project = @attachment.project
-  rescue
-    render_404
+  #rescue
+  #  render_404
   end
 end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 405c5bf44f5b9e761e3898ae37d9bf4451c2ae40..16904c251ca2b70c78196a886bb35743b947942a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -15,6 +15,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
+require 'coderay'
+require 'coderay/helpers/file_type'
+
 module ApplicationHelper
   include Redmine::WikiFormatting::Macros::Definitions
 
@@ -116,6 +119,11 @@ module ApplicationHelper
     l(:actionview_datehelper_select_month_names).split(',')[month-1]
   end
 
+  def syntax_highlight(name, content)
+    type = CodeRay::FileType[name]
+    type ? CodeRay.scan(content, type).html : h(content)
+  end
+  
   def pagination_links_full(paginator, count=nil, options={})
     page_param = options.delete(:page_param) || :page
     url_param = params.dup
diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
index 10f6e739625438559708782dc4e774c95359fdf8..e94ae2e7f31afc26890d2f7f4366e0af44e5888a 100644
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -15,16 +15,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require 'coderay'
-require 'coderay/helpers/file_type'
 require 'iconv'
 
 module RepositoriesHelper
-  def syntax_highlight(name, content)
-    type = CodeRay::FileType[name]
-    type ? CodeRay.scan(content, type).html : h(content)
-  end
-  
   def format_revision(txt)
     txt.to_s[0,8]
   end
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 95de4837a96b87f79c1113df63770ab0221242df..7d6a74ebb9c8d5d1ce36975459968bcc68ded142 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -88,6 +88,10 @@ class Attachment < ActiveRecord::Base
     self.filename =~ /\.(jpe?g|gif|png)$/i
   end
   
+  def is_text?
+    Redmine::MimeType.is_type?('text', filename)
+  end
+  
   def is_diff?
     self.filename =~ /\.(patch|diff)$/i
   end
diff --git a/app/views/attachments/file.rhtml b/app/views/attachments/file.rhtml
new file mode 100644
index 0000000000000000000000000000000000000000..7988d0aedcdaf07dd9766ad37d05beffd5061d50
--- /dev/null
+++ b/app/views/attachments/file.rhtml
@@ -0,0 +1,15 @@
+<h2><%=h @attachment.filename %></h2>
+
+<div class="attachments">
+<p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %>
+   <span class="author"><%= @attachment.author %>, <%= format_time(@attachment.created_on) %></span></p>
+<p><%= link_to l(:button_download), {:controller => 'attachments', :action => 'download', :id => @attachment } -%>
+   <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p>
+
+</div>
+&nbsp;
+<%= render :partial => 'common/file', :locals => {:content => @content, :filename => @attachment.filename} %>
+
+<% content_for :header_tags do -%>
+    <%= stylesheet_link_tag "scm" -%>
+<% end -%>
diff --git a/test/fixtures/attachments.yml b/test/fixtures/attachments.yml
index 162d44720db2ad4e3c9141e3ab5703dddc272f8c..a73d6b385e551f56d5d57db3e9250ae100fb6e09 100644
--- a/test/fixtures/attachments.yml
+++ b/test/fixtures/attachments.yml
@@ -36,4 +36,40 @@ attachments_003:
   filename: logo.gif
   description: This is a logo
   author_id: 2
-  
\ No newline at end of file
+attachments_004: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_source.rb
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 4
+  filesize: 153
+  filename: source.rb
+  author_id: 2
+  description: This is a Ruby source file
+  content_type: application/x-ruby
+attachments_005: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_changeset.diff
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 5
+  filesize: 687
+  filename: changeset.diff
+  author_id: 2
+  content_type: text/x-diff
+attachments_006: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_archive.zip
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 6
+  filesize: 157
+  filename: archive.zip
+  author_id: 2
+  content_type: application/octet-stream
diff --git a/test/fixtures/files/060719210727_archive.zip b/test/fixtures/files/060719210727_archive.zip
new file mode 100644
index 0000000000000000000000000000000000000000..5467885d4b28eedd531d78c32380ffd3e69eded0
Binary files /dev/null and b/test/fixtures/files/060719210727_archive.zip differ
diff --git a/test/fixtures/files/060719210727_changeset.diff b/test/fixtures/files/060719210727_changeset.diff
new file mode 100644
index 0000000000000000000000000000000000000000..af2c2068de002f8c422458850551150b32e6a7e2
--- /dev/null
+++ b/test/fixtures/files/060719210727_changeset.diff
@@ -0,0 +1,13 @@
+Index: trunk/app/controllers/issues_controller.rb
+===================================================================
+--- trunk/app/controllers/issues_controller.rb	(rWision 1483)
++++ trunk/app/controllers/issues_controller.rb	(rWision 1484)
+@@ -149,7 +149,7 @@
+         attach_files(@issue, params[:attachments])
+         flash[:notice] = l(:notice_successful_create)
+         Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
+-        redirect_to :controller => 'issues', :action => 'show', :id => @issue,  :project_id => @project
++        redirect_to :controller => 'issues', :action => 'show', :id => @issue
+         return
+       end		
+     end	
diff --git a/test/fixtures/files/060719210727_source.rb b/test/fixtures/files/060719210727_source.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dccb5916596a4857f6ec32f602dad546e427be3a
--- /dev/null
+++ b/test/fixtures/files/060719210727_source.rb
@@ -0,0 +1,10 @@
+# The Greeter class
+class Greeter
+  def initialize(name)
+    @name = name.capitalize
+  end
+
+  def salute
+    puts "Hello #{@name}!" 
+  end
+end
diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d088c0b0faff8862119ccf5ef56652081ef02e8e
--- /dev/null
+++ b/test/functional/attachments_controller_test.rb
@@ -0,0 +1,59 @@
+# redMine - project management software
+# Copyright (C) 2006-2008  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.dirname(__FILE__) + '/../test_helper'
+require 'attachments_controller'
+
+# Re-raise errors caught by the controller.
+class AttachmentsController; def rescue_action(e) raise e end; end
+
+
+class AttachmentsControllerTest < Test::Unit::TestCase
+  fixtures :users, :projects, :issues, :attachments
+  
+  def setup
+    @controller = AttachmentsController.new
+    @request    = ActionController::TestRequest.new
+    @response   = ActionController::TestResponse.new
+    Attachment.storage_path = "#{RAILS_ROOT}/test/fixtures/files"
+    User.current = nil
+  end
+  
+  def test_show_diff
+    get :show, :id => 5
+    assert_response :success
+    assert_template 'diff'
+  end
+  
+  def test_show_text_file
+    get :show, :id => 4
+    assert_response :success
+    assert_template 'file'
+  end
+  
+  def test_show_other
+    get :show, :id => 6
+    assert_response :success
+    assert_equal 'application/octet-stream', @response.content_type
+  end
+  
+  def test_download_text_file
+    get :download, :id => 4
+    assert_response :success
+    assert_equal 'application/x-ruby', @response.content_type
+  end
+end
diff --git a/test/functional/documents_controller_test.rb b/test/functional/documents_controller_test.rb
index f150a5b7a8693bc8fb658ab960a5ba993f24e4ed..7c1f0213a2edd36656b90f772c336e2951dd3ec0 100644
--- a/test/functional/documents_controller_test.rb
+++ b/test/functional/documents_controller_test.rb
@@ -40,6 +40,8 @@ class DocumentsControllerTest < Test::Unit::TestCase
   
   def test_new_with_one_attachment
     @request.session[:user_id] = 2
+    set_tmp_attachments_directory
+    
     post :new, :project_id => 'ecookbook',
                :document => { :title => 'DocumentsControllerTest#test_post_new',
                               :description => 'This is a new document',
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index 582c27d9b65e6c197f59e837e9d56a72da20d501..32d2a7f41d3c777f5ebaea19d043408422d11ccf 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -361,6 +361,8 @@ class IssuesControllerTest < Test::Unit::TestCase
   end
   
   def test_post_edit_with_attachment_only
+    set_tmp_attachments_directory
+    
     # anonymous user
     post :edit,
          :id => 1,
diff --git a/test/integration/issues_test.rb b/test/integration/issues_test.rb
index b9e21719c2cb6588ae9228a239a1e4dea88a32f9..1b57ba8f821900b73675844669e73a05abb8d45b 100644
--- a/test/integration/issues_test.rb
+++ b/test/integration/issues_test.rb
@@ -1,3 +1,20 @@
+# redMine - project management software
+# Copyright (C) 2006-2008  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require "#{File.dirname(__FILE__)}/../test_helper"
 
 class IssuesTest < ActionController::IntegrationTest
@@ -47,6 +64,7 @@ class IssuesTest < ActionController::IntegrationTest
   # add then remove 2 attachments to an issue
   def test_issue_attachements
     log_user('jsmith', 'jsmith')
+    set_tmp_attachments_directory
 
     post 'issues/edit/1',
          :notes => 'Some notes',
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 61670318a233202cbf63276e7988baff6feadf98..150b063e80ce7c02e5f2c850863101e5ae3579e3 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -57,6 +57,12 @@ class Test::Unit::TestCase
   def test_uploaded_file(name, mime)
     ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + "/files/#{name}", mime)
   end
+  
+  # Use a temporary directory for attachment related tests
+  def set_tmp_attachments_directory
+    Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
+    Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
+  end
 end