diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb
index b50b59dc023c56f80f3815fe093b695b8c2e7706..544b6eb8dc0b2832139e7d87e2ee06aa6aad52cf 100644
--- a/app/controllers/news_controller.rb
+++ b/app/controllers/news_controller.rb
@@ -27,7 +27,23 @@ class NewsController < ApplicationController
       flash[:notice] = l(:notice_successful_update)
       redirect_to :action => 'show', :id => @news
     end
+  end
+  
+  def add_comment
+    @comment = Comment.new(params[:comment])
+    @comment.author = logged_in_user
+    if @news.comments << @comment
+      flash[:notice] = l(:label_comment_added)
+      redirect_to :action => 'show', :id => @news
+    else
+      render :action => 'show'
+    end
   end
+
+  def destroy_comment
+    @news.comments.find(params[:comment_id]).destroy
+    redirect_to :action => 'show', :id => @news
+  end
 
 	def destroy
 		@news.destroy
diff --git a/app/models/comment.rb b/app/models/comment.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1ec7db630f8a6d8680c0bd65874782257dd00d4c
--- /dev/null
+++ b/app/models/comment.rb
@@ -0,0 +1,6 @@
+class Comment < ActiveRecord::Base
+  belongs_to :commented, :polymorphic => true, :counter_cache => true
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+
+  validates_presence_of :commented, :author, :comment
+end
diff --git a/app/models/news.rb b/app/models/news.rb
index faafa7eefa758b6274f8520211d5d76187c5f8ad..f9ba010b079c393d01fc37fc4a787eb7068a3d6b 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -18,6 +18,7 @@
 class News < ActiveRecord::Base
   belongs_to :project
   belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+  has_many :comments, :as => :commented, :dependent => true, :order => "created_on"
   
   validates_presence_of :title, :description
   
diff --git a/app/views/news/show.rhtml b/app/views/news/show.rhtml
index 91df09f0f98733abb6ffef49a8847a02f3c4c19f..890184b1a7a4b6693122a87da6d9a5564275980d 100644
--- a/app/views/news/show.rhtml
+++ b/app/views/news/show.rhtml
@@ -13,4 +13,26 @@
 <% end %>
 </div>
 
-<%= link_to_if_authorized l(:button_edit), :controller => 'news', :action => 'edit', :id => @news %>
+<p><%= link_to_if_authorized l(:button_edit), :controller => 'news', :action => 'edit', :id => @news %></p>
+
+<div id="comments" style="margin-bottom:16px;">
+<h3><%= l(:label_comment_plural) %></h3>
+<% @news.comments.each do |comment| %>
+<% next if comment.new_record? %>
+<h4><%= format_time(comment.created_on) %> - <%= comment.author.name %></h4>
+<div style="float:right;">
+    <small><%= link_to_if_authorized l(:button_delete), {:controller => 'news', :action => 'destroy_comment', :id => @news, :comment_id => comment}, :confirm => l(:text_are_you_sure), :post => true %></small>
+</div>
+<%= simple_format(auto_link(h comment.comment))%>
+<% end if @news.comments_count > 0 %>
+</div>
+
+<% if authorize_for 'news', 'add_comment' %>
+<h3><%= l(:label_comment_add) %></h3>
+<%= start_form_tag :action => 'add_comment', :id => @news %>
+<%= error_messages_for 'comment' %>
+<p><label for="comment_comment"><%= l(:field_comment) %></label><br />
+<%= text_area 'comment', 'comment', :cols => 60, :rows => 6 %></p>
+<%= submit_tag l(:button_add) %>
+<%= end_form_tag %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/projects/list_news.rhtml b/app/views/projects/list_news.rhtml
index 6880de32f05fe79a2f7609d5274f5323ceeb03a7..59b737fc5c1e413fea0bffa2fc2668b8291fbb5b 100644
--- a/app/views/projects/list_news.rhtml
+++ b/app/views/projects/list_news.rhtml
@@ -6,7 +6,8 @@
 <% for news in @news %>
 	<li><%= link_to news.title, :controller => 'news', :action => 'show', :id => news %><br />
 	<% unless news.summary.empty? %><%= news.summary %><br /><% end %>
-	<em><%= news.author.name %>, <%= format_time(news.created_on) %></em><br />&nbsp;
+	<em><%= news.author.name %>, <%= format_time(news.created_on) %></em><br />
+	<%= news.comments_count %> <%= lwr(:label_comment, news.comments_count).downcase %><br />&nbsp;
 	</li>
 <% end %>
 </ul>
diff --git a/db/migrate/010_create_comments.rb b/db/migrate/010_create_comments.rb
new file mode 100644
index 0000000000000000000000000000000000000000..322a019bc3c0a858bba6a7775bbe8f71ececb524
--- /dev/null
+++ b/db/migrate/010_create_comments.rb
@@ -0,0 +1,16 @@
+class CreateComments < ActiveRecord::Migration
+  def self.up
+    create_table :comments do |t|
+      t.column :commented_type, :string, :limit => 30, :default => "", :null => false
+      t.column :commented_id, :integer, :default => 0, :null => false
+      t.column :author_id, :integer, :default => 0, :null => false
+      t.column :comment, :text, :default => "", :null => false
+      t.column :created_on, :datetime, :null => false
+      t.column :updated_on, :datetime, :null => false
+    end
+  end
+
+  def self.down
+    drop_table :comments
+  end
+end
diff --git a/db/migrate/011_add_news_comments_count.rb b/db/migrate/011_add_news_comments_count.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a24743999fe0facb7ce4cb7690d35829f0afa7a1
--- /dev/null
+++ b/db/migrate/011_add_news_comments_count.rb
@@ -0,0 +1,9 @@
+class AddNewsCommentsCount < ActiveRecord::Migration
+  def self.up
+    add_column :news, :comments_count, :integer, :default => 0, :null => false
+  end
+
+  def self.down
+    remove_column :news, :comments_count
+  end
+end
diff --git a/db/migrate/012_add_comments_permissions.rb b/db/migrate/012_add_comments_permissions.rb
new file mode 100644
index 0000000000000000000000000000000000000000..37f075082e4d6fa246604d4f13b80e60d8a8da3c
--- /dev/null
+++ b/db/migrate/012_add_comments_permissions.rb
@@ -0,0 +1,11 @@
+class AddCommentsPermissions < ActiveRecord::Migration
+  def self.up
+    Permission.create :controller => "news", :action => "add_comment", :description => "label_comment_add", :sort => 1130, :is_public => false, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "news", :action => "destroy_comment", :description => "label_comment_delete", :sort => 1133, :is_public => false, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'add_comment']).destroy
+    Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'destroy_comment']).destroy
+  end
+end
diff --git a/lang/de.yml b/lang/de.yml
index 3cff24ed328b10ee68b59f927d704a9183b98ba8..95c2612b5aea8739198e8fb5079019ae10694c65 100644
--- a/lang/de.yml
+++ b/lang/de.yml
@@ -135,6 +135,7 @@ field_onthefly: On-the-fly Benutzerkreation
 field_start_date: Beginn
 field_done_ratio: %% Getan
 field_hide_mail: Mein email address verstecken
+field_comment: Anmerkung
 
 label_user: Benutzer
 label_user_plural: Benutzer
@@ -259,6 +260,11 @@ label_internal: Intern
 label_last_changes: %d änderungen des Letzten
 label_change_view_all: Alle änderungen ansehen
 label_personalize_page: Diese Seite personifizieren
+label_comment: Anmerkung
+label_comment_plural: Anmerkungen
+label_comment_add: Anmerkung addieren
+label_comment_added: Anmerkung fügte hinzu
+label_comment_delete: Anmerkungen löschen
 
 button_login: Einloggen
 button_submit: Einreichen
diff --git a/lang/en.yml b/lang/en.yml
index d64edea78b2f25e257f7bfa4f3a7e7d15918d5ec..4ea41e0e584ddc9a16fafa531a67ab99f5c8a071 100644
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -135,6 +135,7 @@ field_onthefly: On-the-fly user creation
 field_start_date: Start
 field_done_ratio: %% Done
 field_hide_mail: Hide my email address
+field_comment: Comment
 
 label_user: User
 label_user_plural: Users
@@ -259,6 +260,11 @@ label_internal: Internal
 label_last_changes: last %d changes
 label_change_view_all: View all changes
 label_personalize_page: Personalize this page
+label_comment: Comment
+label_comment_plural: Comments
+label_comment_add: Add a comment
+label_comment_added: Comment added
+label_comment_delete: Delete comments
 
 button_login: Login
 button_submit: Submit
diff --git a/lang/es.yml b/lang/es.yml
index 13894955c091a391e278a8f76b6c51e64d23f925..5bdb0e447a81db236c36984218bd1984a0fecc11 100644
--- a/lang/es.yml
+++ b/lang/es.yml
@@ -135,6 +135,7 @@ field_onthefly: Creación del usuario On-the-fly
 field_start_date: Comienzo
 field_done_ratio: %% Realizado
 field_hide_mail: Ocultar mi email address
+field_comment: Comentario
 
 label_user: Usuario
 label_user_plural: Usuarios
@@ -259,6 +260,11 @@ label_internal: Interno
 label_last_changes: %d cambios del último
 label_change_view_all: Ver todos los cambios
 label_personalize_page: Personalizar esta página
+label_comment: Comentario
+label_comment_plural: Comentarios
+label_comment_add: Agregar un comentario
+label_comment_added: Comentario agregó
+label_comment_delete: Suprimir comentarios
 
 button_login: Conexión
 button_submit: Someter
diff --git a/lang/fr.yml b/lang/fr.yml
index cdfabd7dda8fddbd54750dd84d5efa84566e260a..630acd152d8b44187c042096c4bab8c68f230bac 100644
--- a/lang/fr.yml
+++ b/lang/fr.yml
@@ -136,6 +136,7 @@ field_start_date: Début
 field_done_ratio: %% Réalisé
 field_auth_source: Mode d'authentification
 field_hide_mail: Cacher mon adresse mail
+field_comment: Commentaire
 
 label_user: Utilisateur
 label_user_plural: Utilisateurs
@@ -260,6 +261,11 @@ label_internal: Interne
 label_last_changes: %d derniers changements
 label_change_view_all: Voir tous les changements
 label_personalize_page: Personnaliser cette page
+label_comment: Commentaire
+label_comment_plural: Commentaires
+label_comment_add: Ajouter un commentaire
+label_comment_added: Commentaire ajouté
+label_comment_delete: Supprimer les commentaires
 
 button_login: Connexion
 button_submit: Soumettre
diff --git a/lib/tasks/load_default_data.rake b/lib/tasks/load_default_data.rake
index d672802db4f66eebef72841617fc121f7179405a..8f122a4d9e5094d80a3e9b829bf3e9dd4d4915eb 100644
--- a/lib/tasks/load_default_data.rake
+++ b/lib/tasks/load_default_data.rake
@@ -26,11 +26,11 @@ begin
   manager.permissions = Permission.find(:all, :conditions => ["is_public=?", false])
   
   developper = Role.create :name => l(:default_role_developper)
-  perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057]
+  perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1130, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057]
   developper.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"])
   
   reporter = Role.create :name => l(:default_role_reporter)
-  perms = [1050, 1060, 1070, 1057]
+  perms = [1050, 1060, 1070, 1057, 1130]
   reporter.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"])
   
   # trackers
diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css
index 7af699a8bdb793c76af83a5ce875624ebd1ca13e..9b0927a390056b027294ea51e3932fd9c98c4eee 100644
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -446,7 +446,7 @@ img.calendar-trigger {
     margin-left: 4px;
 }
 
-#history h4 {
+#history h4, #comments h4 {
     font-size: 1em;
     margin-bottom: 12px;
     margin-top: 20px;
diff --git a/test/fixtures/comments.yml b/test/fixtures/comments.yml
new file mode 100644
index 0000000000000000000000000000000000000000..24a4546aa8c1f8dca8df6ae80b11af172951cce9
--- /dev/null
+++ b/test/fixtures/comments.yml
@@ -0,0 +1,10 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+comments_001: 
+  commented_type: News
+  commented_id: 1
+  id: 1
+  author_id: 1
+  comment: my first comment
+  created_on: 2006-12-10 18:10:10 +01:00
+  updated_on: 2006-12-10 18:10:10 +01:00
+  
\ No newline at end of file
diff --git a/test/fixtures/news.yml b/test/fixtures/news.yml
index 1bef9184e68f819bb682b9fa820b1a12fbd47279..2c2e2c1346513a2df7725129f1bfb3ce19554ca2 100644
--- a/test/fixtures/news.yml
+++ b/test/fixtures/news.yml
@@ -10,6 +10,7 @@ news_001:
     Visit http://ecookbook.somenet.foo/
   summary: First version was released...
   author_id: 2
+  comments_count: 1
 news_002: 
   created_on: 2006-07-19 22:42:58 +02:00
   project_id: 1
@@ -18,3 +19,4 @@ news_002:
   description: eCookbook 1.0 have downloaded 100,000 times
   summary: eCookbook 1.0 have downloaded 100,000 times
   author_id: 2
+  comments_count: 0
diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4435f0a7fb8f3a8aa7e1fcda9731fa1b928ab78c
--- /dev/null
+++ b/test/unit/comment_test.rb
@@ -0,0 +1,30 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class CommentTest < Test::Unit::TestCase
+  fixtures :users, :news, :comments
+
+  def setup
+    @jsmith = User.find(2)
+    @news = News.find(1)
+  end
+  
+  def test_create
+    comment = Comment.new(:commented => @news, :author => @jsmith, :comment => "my comment")
+    assert comment.save
+    @news.reload
+    assert_equal 2, @news.comments_count
+  end
+
+  def test_validate
+    comment = Comment.new(:commented => @news)
+    assert !comment.save
+    assert_equal 2, comment.errors.length
+  end
+  
+  def test_destroy
+    comment = Comment.find(1)
+    assert comment.destroy
+    @news.reload
+    assert_equal 0, @news.comments_count
+  end
+end