diff --git a/Gemfile b/Gemfile
index 4e8b65d551c76c0192648df98be9f5bb12e0c957..d71163d15932ca9ff2bcee3a681a8066db64ddf2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,7 +31,6 @@ gem 'http_accept_language', :git => 'git://github.com/iain/http_accept_language.
 
 #Standards
 gem 'pubsubhubbub'
-gem 'redfinger', :git => 'git://github.com/rsofaer/redfinger.git'
 
 #EventMachine
 gem 'em-http-request',:ref => 'bf62d67fc72d6e701be5',  :git => 'git://github.com/igrigorik/em-http-request.git', :require => 'em-http'
diff --git a/Gemfile.lock b/Gemfile.lock
index 5c6398084f09a4e8a3bd19ab3f84c627df0944f2..8f731c8616de6798ce8eb11d676e09f88e226eb4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -55,15 +55,6 @@ GIT
     carrierwave (0.5.0)
       activesupport (~> 3.0)
 
-GIT
-  remote: git://github.com/rsofaer/redfinger.git
-  revision: 07721f46d02b9d3aa04880788fecb0b4c1b284d7
-  specs:
-    redfinger (0.0.6)
-      hashie
-      nokogiri (>= 1.4.0)
-      rest-client (>= 1.5.0)
-
 GIT
   remote: git://github.com/rsofaer/sprinkle.git
   revision: 7c744ed158dda1f99a015e6a29d086e80bd8c635
@@ -115,6 +106,7 @@ GEM
       activesupport (= 3.0.1)
     activesupport (3.0.1)
     addressable (2.2.2)
+    archive-tar-minitar (0.5.2)
     arel (1.0.1)
       activesupport (~> 3.0.0)
     aws (2.3.24)
@@ -140,7 +132,6 @@ GEM
       rack (>= 1.0.0)
       rack-test (>= 0.5.4)
       selenium-webdriver (>= 0.0.3)
-    cgi_multipart_eof_fix (2.5.0)
     chef (0.9.12)
       bunny (>= 0.6.0)
       erubis
@@ -192,10 +183,8 @@ GEM
       addressable (~> 2.2.2)
       multipart-post (~> 1.0.1)
       rack (>= 1.1.0, < 2)
-    fastthread (1.0.7)
     ffi (0.6.3)
       rake (>= 0.8.7)
-    gem_plugin (0.2.3)
     gherkin (2.2.9)
       json (~> 1.4.6)
       term-ansicolor (~> 1.0.5)
@@ -211,7 +200,8 @@ GEM
     launchy (0.3.7)
       configuration (>= 0.0.5)
       rake (>= 0.8.1)
-    linecache (0.43)
+    linecache19 (0.5.11)
+      ruby_core_source (>= 0.1.4)
     mail (2.2.9)
       activesupport (>= 2.3.6)
       i18n (~> 0.4.1)
@@ -233,11 +223,6 @@ GEM
     moneta (0.6.0)
     mongo (1.1)
       bson (>= 1.0.5)
-    mongrel (1.1.5)
-      cgi_multipart_eof_fix (>= 2.4)
-      daemons (>= 1.0.3)
-      fastthread (>= 1.0.1)
-      gem_plugin (>= 0.2.3)
     multi_json (0.0.4)
     multipart-post (1.0.1)
     net-ldap (0.1.1)
@@ -332,14 +317,19 @@ GEM
       rspec-expectations (~> 2.0.1)
     rspec-rails (2.0.1)
       rspec (~> 2.0.0)
-    ruby-debug (0.10.3)
-      columnize (>= 0.1)
-      ruby-debug-base (~> 0.10.3.0)
-    ruby-debug-base (0.10.3)
-      linecache (>= 0.3)
+    ruby-debug-base19 (0.11.24)
+      columnize (>= 0.3.1)
+      linecache19 (>= 0.5.11)
+      ruby_core_source (>= 0.1.4)
+    ruby-debug19 (0.11.6)
+      columnize (>= 0.3.1)
+      linecache19 (>= 0.5.11)
+      ruby-debug-base19 (>= 0.11.19)
     ruby-openid (2.1.8)
     ruby-openid-apps-discovery (1.2.0)
       ruby-openid (>= 2.1.7)
+    ruby_core_source (0.1.4)
+      archive-tar-minitar (>= 0.5.2)
     rubyntlm (0.1.1)
     rubyzip (0.9.4)
     selenium-client (1.2.18)
@@ -405,15 +395,13 @@ DEPENDENCIES
   mini_magick
   mocha
   mongo_mapper!
-  mongrel
   omniauth
   pubsubhubbub
   rails (>= 3.0.0)
-  redfinger!
   roxml!
   rspec (>= 2.0.0)
   rspec-rails (>= 2.0.0)
-  ruby-debug
+  ruby-debug19
   sprinkle!
   thin
   twitter
diff --git a/app/controllers/albums_controller.rb b/app/controllers/albums_controller.rb
index a74143363115c1c03a4cb1039ad70153eb94a4da..1474b5c0f56f83ba4a72503d98818d8a514a3659 100644
--- a/app/controllers/albums_controller.rb
+++ b/app/controllers/albums_controller.rb
@@ -17,8 +17,13 @@ class AlbumsController < ApplicationController
     aspect = params[:album][:to]
 
     @album = current_user.post(:album, params[:album])
-    flash[:notice] = I18n.t 'albums.create.success', :name  => @album.name
-    redirect_to :action => :show, :id => @album.id, :aspect => aspect
+    if @album.persisted?
+      flash[:notice] = I18n.t 'albums.create.success', :name  => @album.name
+      redirect_to :action => :show, :id => @album.id, :aspect => aspect
+    else
+      flash[:error] = I18n.t 'albums.create.failure'
+      redirect_to albums_path(:aspect => aspect)
+    end
   end
 
   def new
diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb
index ea56ed81b4f6ba571c370c631d6e8174505b9935..9280e2d3eeecce2e682dd323e8a72afa3a945b5c 100644
--- a/app/controllers/people_controller.rb
+++ b/app/controllers/people_controller.rb
@@ -56,6 +56,7 @@ class PeopleController < ApplicationController
     end
 
     # upload and set new profile photo
+    params[:person][:profile] ||= {}
     if params[:person][:profile][:image].present?
       raw_image = params[:person][:profile].delete(:image)
       params[:profile_image_hash] = { :user_file => raw_image, :to => "all" }
diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb
index ae00cc7df6b7b400d6deebfe11df6076826280e6..a5dd347e5d1ddbb8fd507fdbe398c22c4e9d7ecc 100644
--- a/app/controllers/publics_controller.rb
+++ b/app/controllers/publics_controller.rb
@@ -11,7 +11,7 @@ class PublicsController < ApplicationController
   def hcard
     @person = Person.find_by_id params[:id]
     unless @person.nil? || @person.owner.nil?
-      render 'hcard'
+      render 'publics/hcard'
     else
       render :nothing => true, :status => 404
     end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index b5e11f86a34a05b4774354010526858e74f5b140..a96438dc21b2fefbdf97cfb6bfbb11ef71da5c3a 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -5,11 +5,9 @@
 class UsersController < ApplicationController
   require File.join(Rails.root, 'lib/diaspora/ostatus_builder')
   require File.join(Rails.root, 'lib/diaspora/exporter')
-  require File.join(Rails.root, 'lib/diaspora/importer')
   require File.join(Rails.root, 'lib/collect_user_photos')
 
-
-  before_filter :authenticate_user!, :except => [:new, :create, :public, :import]
+  before_filter :authenticate_user!, :except => [:new, :create, :public]
 
   respond_to :html
 
@@ -101,23 +99,4 @@ class UsersController < ApplicationController
     User.invite!(:email => params[:email])
   end
   
-  
-  def import
-    xml = params[:upload][:file].read
-
-    begin
-      importer = Diaspora::Importer.new(Diaspora::Parsers::XML)
-      importer.execute(xml, params[:user])
-      flash[:notice] = "hang on a sec, try logging in!"
-
-    rescue Exception => e
-      flash[:error] = "Something went wrong: #{e.message}"
-    end
-
-      redirect_to new_user_registration_path
-    #redirect_to user_session_path
-  end
-
-
-
 end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 0060f015606103adc0a9f10fdfe242710cd35416..ba0a57a950f44600f7b255bc2a8f963fcc8a62e2 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -3,6 +3,8 @@
 #   the COPYRIGHT file.
 
 module ApplicationHelper
+  @@youtube_title_cache = Hash.new("no-title")
+
   def current_aspect?(aspect)
     !@aspect.is_a?(Symbol) && @aspect.id == aspect.id
   end
@@ -85,4 +87,86 @@ module ApplicationHelper
       
     "#{photos_path}?person_id=#{person_id}"
   end
+
+  def markdownify(message, options = {})
+    message = h(message).html_safe
+
+    [:autolinks, :youtube, :emphasis, :links].each do |k|
+      if !options.has_key?(k)
+        options[k] = true
+      end
+    end
+
+    if options[:links]
+      message.gsub!(/\[([^\[]+)\]\(([^ ]+) \&quot;(([^&]|(&[^q])|(&q[^u])|(&qu[^o])|(&quo[^t])|(&quot[^;]))+)\&quot;\)/) do |m|
+        escape = (options[:emphasis]) ? "\\" : ""
+        res = "<a target=\"#{escape}_blank\" href=\"#{$2}\" title=\"#{$3}\">#{$1}</a>"
+        res
+      end
+      message.gsub!(/\[([^\[]+)\]\(([^ ]+)\)/) do |m|
+        escape = (options[:emphasis]) ? "\\" : ""
+        res = "<a target=\"#{escape}_blank\" href=\"#{$2}\">#{$1}</a>"
+        res
+      end
+    end
+
+    if options[:youtube]
+      message.gsub!(/( |^)(http:\/\/)?www\.youtube\.com\/watch[^ ]*v=([A-Za-z0-9_]+)(&[^ ]*|)/) do |m|
+        res = "#{$1}youtube.com::#{$3}"
+        res.gsub!(/(\*|_)/) { |m| "\\#{$1}" } if options[:emphasis]
+        res
+      end
+    end
+
+    if options[:autolinks]
+      message.gsub!(/( |^)(www\.[^ ]+\.[^ ])/, '\1http://\2')
+      message.gsub!(/(<a target="\\?_blank" href=")?(https|http|ftp):\/\/([^ ]+)/) do |m|
+        if !$1.nil?
+          m
+        else
+          res = %{<a target="_blank" href="#{$2}://#{$3}">#{$3}</a>}
+          res.gsub!(/(\*|_)/) { |m| "\\#{$1}" } if options[:emphasis]
+          res
+        end
+      end
+    end
+
+    if options[:emphasis]
+      message.gsub!(/([^\\]|^)\*\*(([^*]|([^*]\*[^*]))*[^*\\])\*\*/, '\1<strong>\2</strong>')
+      message.gsub!(/([^\\]|^)__(([^_]|([^_]_[^_]))*[^_\\])__/, '\1<strong>\2</strong>')
+      message.gsub!(/([^\\]|^)\*([^*]*[^\\])\*/, '\1<em>\2</em>')
+      message.gsub!(/([^\\]|^)_([^_]*[^\\])_/, '\1<em>\2</em>')
+      message.gsub!(/([^\\]|^)\*/, '\1')
+      message.gsub!(/([^\\]|^)_/, '\1')
+      message.gsub!("\\*", "*")
+      message.gsub!("\\_", "_")
+    end
+
+    if options[:youtube]
+      while youtube = message.match(/youtube\.com::([A-Za-z0-9_\\]+)/)
+        videoid = youtube[1]
+        message.gsub!('youtube.com::'+videoid, '<a onclick="openVideo(\'youtube.com\', \'' + videoid + '\', this)" href="#video">Youtube: ' + youtube_title(videoid) + '</a>')
+      end
+    end
+
+    return message
+  end
+
+  def youtube_title(id)
+    unless @@youtube_title_cache[id] == 'no-title'
+      return @@youtube_title_cache[id]
+    end
+
+    ret = 'Unknown Video Title' #TODO add translation
+    http = Net::HTTP.new('gdata.youtube.com', 80)
+    path = '/feeds/api/videos/'+id+'?v=2'
+    resp, data = http.get(path, nil)
+    title = data.match(/<title>(.*)<\/title>/)
+    unless title.nil?
+      ret = title.to_s[7..-9]
+    end
+
+    @@youtube_title_cache[id] = ret;
+    return ret
+  end
 end
diff --git a/app/helpers/status_messages_helper.rb b/app/helpers/status_messages_helper.rb
index 2e010715aaf99ce410f6b860128bfee95b57eb99..2dfbd31cccebfd08c4da3d55f9ba55c480fca28f 100644
--- a/app/helpers/status_messages_helper.rb
+++ b/app/helpers/status_messages_helper.rb
@@ -3,8 +3,6 @@
 #   the COPYRIGHT file.
 
 module StatusMessagesHelper
-  @@youtube_title_cache = Hash.new("no-title")
-
   def my_latest_message
     unless @latest_status_message.nil?
       return @latest_status_message.message
@@ -12,39 +10,4 @@ module StatusMessagesHelper
       return I18n.t('status_messages.helper.no_message_to_display')
     end
   end
-
-  def make_links(message)
-    # If there should be some kind of bb-style markup, email/diaspora highlighting, it could go here.
-    
-    # next line is important due to XSS! (h is rail's make_html_safe-function)
-    message = h(message).html_safe
-    message.gsub!(/( |^)(www\.[^ ]+\.[^ ])/, '\1http://\2')
-    message.gsub!(/( |^)http:\/\/www\.youtube\.com\/watch[^ ]*v=([A-Za-z0-9_]+)(&[^ ]*|)/, '\1youtube.com::\2')
-    message.gsub!(/(https|http|ftp):\/\/([^ ]+)/, '<a target="_blank" href="\1://\2">\2</a>')
-   
-    while youtube = message.match(/youtube\.com::([A-Za-z0-9_]+)/)
-      videoid = youtube[1]
-      message.gsub!('youtube.com::'+videoid, '<a onclick="openVideo(\'youtube.com\', \'' + videoid + '\', this)" href="#video">Youtube: ' + youtube_title(videoid) + '</a>')
-    end
-    return message
-  end
-
-  def youtube_title(id)
-    unless @@youtube_title_cache[id] == 'no-title'
-      return @@youtube_title_cache[id]
-    end
-
-    ret = 'Unknown Video Title' #TODO add translation
-    http = Net::HTTP.new('gdata.youtube.com', 80)
-    path = '/feeds/api/videos/'+id+'?v=2'
-    resp, data = http.get(path, nil)
-    title = data.match(/<title>(.*)<\/title>/)
-    unless title.nil?
-      ret = title.to_s[7..-9]
-    end
-    
-    @@youtube_title_cache[id] = ret;
-    return ret
-  end
-
 end
diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb
index c0626f387cbab6c94e0142da2ad0451cf1b4b414..36047d0593277c4b173bbe0b31aba645f44dabd3 100644
--- a/app/mailers/notifier.rb
+++ b/app/mailers/notifier.rb
@@ -2,12 +2,12 @@ class Notifier < ActionMailer::Base
   include Magent::Async
   
   default :from => "no-reply@joindiaspora.com"
-  ATTACHMENT =  File.read("#{Rails.root}/public/images/diaspora_caps.png")  
+  ATTACHMENT =  File.read("#{Rails.root}/public/images/diaspora_white_on_grey.png")  
 
   def new_request(recipient, sender)
     @receiver = recipient
     @sender = sender
-    attachments["diaspora_white.png"] = ATTACHMENT 
+    attachments.inline['diaspora_white_on_grey.png'] = ATTACHMENT 
 
     mail(:to => "#{recipient.real_name} <#{recipient.email}>",
     :subject => "new Diaspora* friend request from #{@sender.real_name}", :host => APP_CONFIG[:terse_pod_url])
@@ -17,7 +17,8 @@ class Notifier < ActionMailer::Base
     @receiver = recipient
     @sender = sender
     @aspect = aspect
-    attachments["diaspora_white.png"] = ATTACHMENT 
+    attachments.inline['diaspora_white_on_grey.png'] = ATTACHMENT 
+
     mail(:to => "#{recipient.real_name} <#{recipient.email}>",
     :subject => "#{@sender.real_name} has accepted your friend request on Diaspora*", :host => APP_CONFIG[:terse_pod_url])
   end
diff --git a/app/models/album.rb b/app/models/album.rb
index fbc64b2cf33673056097bf7ab89b1f66a2e4bb1b..9be93701ca0d707de643c5ded7db0b6973dc7ffd 100644
--- a/app/models/album.rb
+++ b/app/models/album.rb
@@ -32,6 +32,10 @@ class Album < Post
     p_photo ? p_photo : self.photos.sort(:created_at.desc).last
   end
 
+  def mutable?
+    true
+  end
+
   protected
   def destroy_photos
     self.photos.each{|p| p.destroy}
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 9ae22357933f7b50f21c4c5463b4e42345fd7950..5aef552926cb836b40b660d2b1139e7f82bb140e 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -4,8 +4,7 @@
 
 class Contact
   include MongoMapper::Document
-  attr_accessor :aspect_names #this is only used in the importer
-  
+
   belongs_to :user
   validates_presence_of :user
 
diff --git a/app/models/person.rb b/app/models/person.rb
index 53f9b3afefa59c3faa3fd7b8a6cc722d6f232db3..f99908eacae2c8885cfdc561f7d4c0f30f905a57 100644
--- a/app/models/person.rb
+++ b/app/models/person.rb
@@ -43,8 +43,10 @@ class Person
 
   ensure_index :diaspora_handle
 
+  scope :searchable, where('profile.searchable' => true)
+
   def self.search(query)
-    return Person.all if query.to_s.empty?
+    return Person.searchable.all if query.to_s.empty?
     query_tokens = query.to_s.strip.split(" ")
     full_query_text = Regexp.escape(query.to_s.strip)
 
@@ -52,8 +54,9 @@ class Person
 
     query_tokens.each do |token|
       q = Regexp.escape(token.to_s.strip)
-      p = Person.all('profile.first_name' => /^#{q}/i) \
- | Person.all('profile.last_name' => /^#{q}/i) \
+      p = Person.searchable.all('profile.first_name' => /^#{q}/i) \
+ | Person.searchable.all('profile.last_name' => /^#{q}/i) \
+ | Person.searchable.all('diaspora_handle' => /^#{q}/i) \
  | p
     end
   
@@ -120,7 +123,10 @@ class Person
     #hcard_profile = HCard.find profile.hcard.first[:href]
     Rails.logger.info("hcard: #{ hcard.inspect}")
     new_person.url = hcard[:url]
-    new_person.profile = Profile.new(:first_name => hcard[:given_name], :last_name => hcard[:family_name], :image_url => hcard[:photo])
+    new_person.profile = Profile.new( :first_name => hcard[:given_name],
+                                      :last_name  => hcard[:family_name],
+                                      :image_url  => hcard[:photo],
+                                      :searchable => hcard[:searchable])
 
     new_person.save! ? new_person : nil
   end
diff --git a/app/models/photo.rb b/app/models/photo.rb
index bce9d469da3206e0c4b2efa7fe4c66cacfe8a087..6c96e425cebcbec153c1ac1ae8b7c8e81769c037 100644
--- a/app/models/photo.rb
+++ b/app/models/photo.rb
@@ -38,6 +38,7 @@ class Photo < Post
     person = params.delete(:person)
 
     photo = Photo.new(params)
+    photo.diaspora_handle = params[:diaspora_handle]
 
     photo.image.store! image_file
     photo.person = person
@@ -74,5 +75,9 @@ class Photo < Post
   def thumb_hash
     {:thumb_url => url(:thumb_medium), :id => id, :album_id => album_id}
   end
+
+  def mutable?
+    true
+  end
 end
 
diff --git a/app/models/post.rb b/app/models/post.rb
index 298d25b5fcb8051f341bcd4d13f9678649aaa489..842af2b2e194fa0904dc3b992f9cf3cd87dc3022 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -50,6 +50,10 @@ class Post
     }
   end
 
+  def mutable?
+    false
+  end
+
   protected
   def destroy_comments
     comments.each{|c| c.destroy}
diff --git a/app/models/profile.rb b/app/models/profile.rb
index d69c64e1253674d0840145f414d4e4f120bd4b1b..b8383de176c5a776f0faac7f432e52cc3e27019d 100644
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -8,25 +8,27 @@ class Profile
   include Diaspora::Webhooks
   include ROXML
 
+  xml_reader :diaspora_handle
   xml_reader :first_name
   xml_reader :last_name
   xml_reader :image_url
   xml_reader :birthday
   xml_reader :gender
   xml_reader :bio
-  xml_accessor :diaspora_handle
+  xml_reader :searchable
 
+  key :diaspora_handle, String
   key :first_name, String
   key :last_name,  String
   key :image_url,  String
   key :birthday,   Date
   key :gender,     String
   key :bio,        String
-  key :diaspora_handle, String
+  key :searchable, Boolean, :default => true
 
   after_validation :strip_names
   validates_length_of :first_name, :maximum => 32
-  validates_length_of :last_name, :maximum => 32
+  validates_length_of :last_name,  :maximum => 32
 
   before_save :strip_names
 
diff --git a/app/models/user.rb b/app/models/user.rb
index bb465e78ae560b81dca10077fe40978228a7342a..516a6cc71e391fb2fae7751c707ae72eb9b482a4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -22,11 +22,11 @@ class User
   key :invites, Integer, :default => 5
   key :invitation_token, String
   key :invitation_sent_at, DateTime
-  key :inviter_ids, Array, :typecast => 'ObjectId' 
-  key :friend_ids, Array, :typecast => 'ObjectId' 
-  key :pending_request_ids, Array, :typecast => 'ObjectId' 
-  key :visible_post_ids, Array, :typecast => 'ObjectId' 
-  key :visible_person_ids, Array, :typecast => 'ObjectId' 
+  key :inviter_ids, Array, :typecast => 'ObjectId'
+  key :friend_ids, Array, :typecast => 'ObjectId'
+  key :pending_request_ids, Array, :typecast => 'ObjectId'
+  key :visible_post_ids, Array, :typecast => 'ObjectId'
+  key :visible_person_ids, Array, :typecast => 'ObjectId'
 
   key :invite_messages, Hash
 
@@ -39,9 +39,8 @@ class User
 
   validates_presence_of :username
   validates_uniqueness_of :username, :case_sensitive => false
-  validates_format_of :username, :with => /\A[A-Za-z0-9_.]+\z/ 
+  validates_format_of :username, :with => /\A[A-Za-z0-9_.]+\z/
   validates_length_of :username, :maximum => 32
-  
   validates_inclusion_of :language, :in => AVAILABLE_LANGUAGE_CODES
 
   validates_presence_of :person, :unless => proc {|user| user.invitation_token.present?}
@@ -61,6 +60,11 @@ class User
   #after_create :seed_aspects
 
   before_destroy :unfriend_everyone, :remove_person
+  before_save do
+    person.save if person
+  end
+
+  attr_accessible :getting_started, :password, :password_confirmation, :language, 
 
   def strip_and_downcase_username
     if username.present?
@@ -98,11 +102,11 @@ class User
 
   def move_friend(opts = {})
     return true if opts[:to] == opts[:from]
-    if opts[:friend_id] && opts[:to] && opts[:from] 
+    if opts[:friend_id] && opts[:to] && opts[:from]
       from_aspect = self.aspects.first(:_id => opts[:from])
       posts_to_move = from_aspect.posts.find_all_by_person_id(opts[:friend_id])
       if add_person_to_aspect(opts[:friend_id], opts[:to], :posts => posts_to_move)
-        delete_person_from_aspect(opts[:friend_id], opts[:from], :posts => posts_to_move) 
+        delete_person_from_aspect(opts[:friend_id], opts[:from], :posts => posts_to_move)
         return true
       end
     end
@@ -116,7 +120,7 @@ class User
     raise 'Can not add person who is already in the aspect' if aspect.people.include?(contact)
     contact.aspects << aspect
     opts[:posts] ||= self.raw_visible_posts.all(:person_id => person_id)
-    
+
     aspect.posts += opts[:posts]
     contact.save
     aspect.save
@@ -146,15 +150,16 @@ class User
 
     post = build_post(class_name, options)
 
-    post.socket_to_uid(id, :aspect_ids => aspect_ids) if post.respond_to?(:socket_to_uid)
-    push_to_aspects(post, aspect_ids)
-    
-    if options[:public] == true
-      self.services.each do |service|
-        self.send("post_to_#{service.provider}".to_sym, service, post.message)
+    if post.persisted?
+      Rails.logger.info("Pushing: #{post.inspect} out to aspects")
+      push_to_aspects(post, aspect_ids)
+      post.socket_to_uid(id, :aspect_ids => aspect_ids) if post.respond_to?(:socket_to_uid)
+      if options[:public] == true
+        self.services.each do |service|
+          self.send("post_to_#{service.provider}".to_sym, service, post.message)
+        end
       end
     end
-
     post
   end
 
@@ -324,14 +329,14 @@ class User
         raise "Must invite to your aspect"
       else
         u = User.find_by_email(opts[:email])
-        if u.nil?  
+        if u.nil?
         elsif friends.include?(u.person)
-          raise "You are already friends with this person"          
+          raise "You are already friends with this person"
         elsif not u.invited?
           self.send_friend_request_to(u.person, aspect_object)
           return
         elsif u.invited? && u.inviters.include?(self)
-          raise "You already invited this person"          
+          raise "You already invited this person"
         end
       end
       request = Request.instantiate(
@@ -402,16 +407,22 @@ class User
 
   ###Helpers############
   def self.build(opts = {})
+    u = User.new(opts)
+
+    u.username = opts[:username]
+    u.email = opts[:email]
+
     opts[:person] ||= {}
     opts[:person][:profile] ||= Profile.new
-    opts[:person][:diaspora_handle] = "#{opts[:username]}@#{APP_CONFIG[:terse_pod_url]}"
-    opts[:person][:url] = APP_CONFIG[:pod_url]
+    u.person = Person.new(opts[:person])
+    u.person.diaspora_handle = "#{opts[:username]}@#{APP_CONFIG[:terse_pod_url]}"
 
-    opts[:serialized_private_key] = generate_key
-    opts[:person][:serialized_public_key] = opts[:serialized_private_key].public_key
+    u.person.url = APP_CONFIG[:pod_url]
 
+    new_key = generate_key
+    u.serialized_private_key = new_key
+    u.person.serialized_public_key = new_key.public_key
 
-    u = User.new(opts)
     u
   end
 
@@ -420,10 +431,6 @@ class User
     self.aspects.create(:name => "Work")
   end
 
-  def diaspora_handle
-    person.diaspora_handle
-  end
-
   def as_json(opts={})
     {
       :user => {
@@ -437,7 +444,8 @@ class User
 
 
   def self.generate_key
-    OpenSSL::PKey::RSA::generate 4096
+    key_size = (Rails.env == 'test' ? 512 : 4096)
+    OpenSSL::PKey::RSA::generate key_size
   end
 
   def encryption_key
diff --git a/app/views/js/_websocket_js.haml b/app/views/js/_websocket_js.haml
index ec9854bb69e29f1d501c2b94b79dd01ae05d25d0..33fb0e97189c7ac1fbe9101220af926f81c2d14c 100644
--- a/app/views/js/_websocket_js.haml
+++ b/app/views/js/_websocket_js.haml
@@ -8,7 +8,7 @@
   $(document).ready(function(){
     function debug(str){ $("#debug").append("<p>" +  str); };
 
-    ws = new WebSocket("ws://#{request.host}:#{APP_CONFIG[:socket_port]}/#{CGI::escape(current_user.id.to_s)}");
+    ws = new WebSocket("ws://#{request.host}:#{APP_CONFIG[:socket_port]}/");
 
   //Attach onmessage to websocket
     ws.onmessage = function(evt) {
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 70f610ebc62d44bee0cd96065de3f1e9f44b83f5..5fc9f3b51fa821db1c08d35f29ed4a191339b2cd 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -3,7 +3,7 @@
 -#   the COPYRIGHT file.
 
 !!!
-%html
+%html{:lang => I18n.locale.to_s}
   %head
     %title
       = "#{current_user.real_name} | diaspora" if current_user
@@ -43,7 +43,7 @@
 
     %header
       .container{:style => "position:relative;"}
-        #diaspora_text{:href => root_path}
+        #diaspora_text
           = link_to "DIASPORA", (current_user ? root_path : new_user_session_path)
           %span.sub_text
             PREVIEW
diff --git a/app/views/notifier/new_request.html.haml b/app/views/notifier/new_request.html.haml
index 66bb56f1a162a998de7c1c02f970c103d157b984..1a994695a1917ea455dd33eab793685dd4f1e204 100644
--- a/app/views/notifier/new_request.html.haml
+++ b/app/views/notifier/new_request.html.haml
@@ -43,7 +43,7 @@
       }
   %body
     %header
-      = image_tag 'diaspora_white.png'
+      = image_tag attachments['diaspora_white_on_grey.png'].url, :alt => "DIASPORA"
     #container
       %p
         Hello #{@receiver.profile.first_name}!
diff --git a/app/views/notifier/request_accepted.html.haml b/app/views/notifier/request_accepted.html.haml
index 191f8f42ce292af096106632686c0af541c474a7..15ca54647ce81d11f13cc89680afa0df63b96361 100644
--- a/app/views/notifier/request_accepted.html.haml
+++ b/app/views/notifier/request_accepted.html.haml
@@ -43,7 +43,7 @@
       }
   %body
     %header
-      = image_tag 'diaspora_white.png'
+      = image_tag attachments['diaspora_white_on_grey.png'].url, :alt => "DIASPORA"
     #container
       %p
         Hello #{@receiver.profile.first_name}!
diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml
index d3b8b135d157e8432d9b7073863de6ec696b570d..79440c94e115a2d554365c954379afd19167b3cd 100644
--- a/app/views/people/edit.html.haml
+++ b/app/views/people/edit.html.haml
@@ -44,6 +44,12 @@
         = t('.your_photo')
         = render 'people/profile_photo_upload', :form => profile
 
+      %h4
+        Search
+        %p{:class=>"checkbox_select"}
+          = profile.label :searchable, "Allow for people to search for you"
+          = profile.check_box :searchable, {:checked => @person.profile.searchable}, true, false
+
     .submit_block
       = link_to t('cancel'), edit_user_path(current_user)
       = t('or')
diff --git a/app/views/publics/hcard.erb b/app/views/publics/hcard.erb
deleted file mode 100644
index c02d909b5d05163d05093c76472ad122d4a24925..0000000000000000000000000000000000000000
--- a/app/views/publics/hcard.erb
+++ /dev/null
@@ -1,44 +0,0 @@
-<div id="content">
-  <h1><%=@person.real_name%></h1>
-  <div id="content_inner">
-    <div id="i" class="entity_profile vcard author">
-      <h2>User profile</h2>
-      <dl class="entity_nickname">
-        <dt>Nickname</dt>
-        <dd>
-        <a href="<%=@person.url%>" rel="me" class="nickname url uid"><%= @person.real_name%></a>
-        </dd>
-      </dl>
-        <dl class="entity_given_name">
-        <dt>First name</dt>
-        <dd>
-        <span class="given_name" ><%= @person.profile.first_name %></span>
-        </dd>
-        </dl>
-        <dl class="entity_family_name">
-        <dt>Family name</dt>
-        <dd>
-        <span class="family_name" ><%= @person.profile.last_name %></span>
-        </dd>
-        </dl>
-        <dl class="entity_fn">
-        <dt>Full name</dt>
-        <dd>
-        <span class="fn" ><%= @person.real_name %></span>
-        </dd>
-      </dl>
-      <dl class="entity_url">
-        <dt>URL</dt>
-        <dd>
-        <a href="<%= @person.url%>" rel="me" id="pod_location" class="url"><%= @person.url%></a>
-        </dd>
-      </dl>
-      <dl class="entity_photo">
-        <dt>Photo</dt>
-        <dd>
-        <img class="photo avatar" src="<%= image_or_default(@person)%>" width="100" height="100"/>
-        </dd>
-      </dl>
-    </div>
-  </div>
-</div>
diff --git a/app/views/publics/hcard.haml b/app/views/publics/hcard.haml
new file mode 100644
index 0000000000000000000000000000000000000000..8692869640f7d795db2c6daccedb176899968cec
--- /dev/null
+++ b/app/views/publics/hcard.haml
@@ -0,0 +1,40 @@
+#content
+  %h1= @person.real_name
+  #content_inner
+    #i.entity_profile.vcard.author
+      %h2 User profile
+
+      %dl.entity_nickname
+        %dt Nickname
+        %dd
+          %a.nickname.url.uid{:href=>@person.url, :rel=>'me'}= @person.real_name
+
+      %dl.entity_given_name
+        %dt First name
+        %dd
+          %span.given_name= @person.profile.first_name
+
+      %dl.entity_family_name
+        %dt Family name
+        %dd
+          %span.family_name= @person.profile.last_name
+
+      %dl.entity_fn
+        %dt Full name
+        %dd
+          %span.fn= @person.real_name
+
+      %dl.entity_url
+        %dt URL
+        %dd
+          %a#pod_location.url{:href=>@person.url, :rel=>'me'}= @person.url
+
+      %dl.entity_photo
+        %dt Photo
+        %dd
+          %img.photo.avatar{:src=>image_or_default(@person), :width=>'100px', :height=>'100px'}
+
+      %dl.entity_searchable
+        %dt Searchable
+        %dd
+          %span.searchable= @person.profile.searchable
diff --git a/app/views/registrations/new.html.haml b/app/views/registrations/new.html.haml
index 41423e55e79275ccb9936a3ae7ea2682107a3f42..f6cd28981f591c4586ef291495cca9dda963dc4e 100644
--- a/app/views/registrations/new.html.haml
+++ b/app/views/registrations/new.html.haml
@@ -19,24 +19,3 @@
 
       = f.submit t('.sign_up')
 
-
-  .floating
-    %h3
-      = t('.upload_existing_account')
-
-    = form_tag '/users/import', :multipart => true do
-
-      %p
-        = label_tag 'user[email]'
-        = text_field_tag 'user[email]'
-      %p
-        = label_tag 'user[password]'
-        = password_field_tag 'user[password]'
-      %p
-        = label_tag 'user[password_confirmation]'
-        = password_field_tag 'user[password_confirmation]'
-
-      %label Select File
-      = file_field 'upload', 'file'
-      = submit_tag t('.upload')
-
diff --git a/app/views/requests/_new_request.haml b/app/views/requests/_new_request.haml
index 05ce611882197b882c25a67adfc49c19c733e421..b4d7c25bd68658ca1dde653fec9d4a8e4be87fa5 100644
--- a/app/views/requests/_new_request.haml
+++ b/app/views/requests/_new_request.haml
@@ -10,7 +10,7 @@
 
   = render 'shared/add_friend_dropdown', :aspect => aspect, :friends => current_user.friends_not_in_aspect(aspect), :manage => defined?(manage)
 
-  = form_for Request.new do |fr_request|
+  = form_for(Request.new, :html => {:id => "new_request_to_#{aspect.id}"}) do |fr_request|
     = fr_request.error_messages
 
     =t('.enter_a_diaspora_username')
@@ -18,8 +18,8 @@
     %i= t '.your_diaspora_username_is', :diaspora_handle  => current_user.diaspora_handle
 
     %p
-      = fr_request.label :destination_url, t('.friends_username')
-      = fr_request.text_field :destination_url
+      = fr_request.label :destination_url, t('.friends_username'), :for => "request_d_url_to_#{aspect.id}"
+      = fr_request.text_field :destination_url, :id => "request_d_url_to_#{aspect.id}"
     = fr_request.hidden_field :aspect_id, :value => aspect.id
 
     - if defined?(getting_started)
diff --git a/app/views/shared/_add_friend_dropdown.html.haml b/app/views/shared/_add_friend_dropdown.html.haml
index 062f534b8f32973e3c89e01998eec73304012e34..f324b988ce43b0b17ba9940be497fed6439fee09 100644
--- a/app/views/shared/_add_friend_dropdown.html.haml
+++ b/app/views/shared/_add_friend_dropdown.html.haml
@@ -1,5 +1,5 @@
 
-= form_tag '/aspects/add_to_aspect', :id => 'add_to_aspect' do
+= form_tag '/aspects/add_to_aspect', :id => "add_to_aspect_#{aspect.id}" do
   = select_tag :friend_id, options_from_collection_for_select(friends, "id", "real_name"), :include_blank => true
   = hidden_field_tag :aspect_id, aspect.id
   - if defined?(manage) && manage
diff --git a/app/views/shared/_publisher.haml b/app/views/shared/_publisher.haml
index 94f7737d79acce40ff08224b28121269dfb37da9..c2ced4804cbaf414b977d71c65d8da3332780e0b 100644
--- a/app/views/shared/_publisher.haml
+++ b/app/views/shared/_publisher.haml
@@ -32,6 +32,11 @@
       = status.hidden_field :to, :value => (aspect == :all ? aspect : aspect.id)
 
       .options_and_submit
+        - if aspect == :all
+          = status.submit t('.share'), :title => "Share with all aspects"
+        - else
+          = status.submit t('.share'), :title => "Share with #{aspect}"
+
         - if aspect == :all
           .public_toggle
             = status.check_box( :public, {}, true, false )
@@ -42,10 +47,6 @@
               #question_mark_pane
                 = render 'shared/public_explain'
 
-        - if aspect == :all
-          = status.submit t('.share'), :title => "Share with all aspects"
-        - else
-          = status.submit t('.share'), :title => "Share with #{aspect}"
 
     #publisher_photo_upload
       = t('or')
diff --git a/app/views/status_messages/_status_message.html.haml b/app/views/status_messages/_status_message.html.haml
index f78f4d40574fbe98e4840b0198ee9cb82800e696..19f0b1bd3791c612d2f09f294f0f89db5ac402c6 100644
--- a/app/views/status_messages/_status_message.html.haml
+++ b/app/views/status_messages/_status_message.html.haml
@@ -23,7 +23,7 @@
           = render "shared/reshare", :post => post, :current_user => current_user
           = link_to t('delete'), status_message_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete"
 
-    = make_links(post.message)
+    = markdownify(post.message)
 
     .info
       %span.time= link_to(how_long_ago(post), object_path(post))
diff --git a/app/views/status_messages/show.html.haml b/app/views/status_messages/show.html.haml
index 8ab8d3a3522dee5ff16725d4f14a0f0f04b2e798..108580a3eac177c709c9e0fcfd9fd50e1575a5cc 100644
--- a/app/views/status_messages/show.html.haml
+++ b/app/views/status_messages/show.html.haml
@@ -7,7 +7,7 @@
 
 .span-14.append-1.last
   %h1.show_text
-    = make_links(@status_message.message)
+    = markdownify(@status_message.message)
 
   = how_long_ago(@status_message)
 
diff --git a/app/views/users/getting_started/_step_1.html.haml b/app/views/users/getting_started/_step_1.html.haml
index 6ee9002117bfeacf73beb9743d34982d913f768c..56e5638b37c5b009d02cb2bab9325c38f6dda61b 100644
--- a/app/views/users/getting_started/_step_1.html.haml
+++ b/app/views/users/getting_started/_step_1.html.haml
@@ -35,6 +35,12 @@
       Your photo
       = render 'people/profile_photo_upload', :form => profile
 
+    %h4
+      Search
+      %p{:class=>"checkbox_select"}
+        = profile.label :searchable, "Allow for people to search for you"
+        = profile.check_box :searchable, {:checked => @person.profile.searchable}, true, false
+
     = hidden_field_tag :getting_started, @step
 
   .submit_block
diff --git a/config/locales/devise/devise.de.yml b/config/locales/devise/devise.de.yml
index 543ab19350ffb3f7cf13f7e212c1a0b3be057a4f..ebbb2baa133b38087074717186b36d486b686ffe 100644
--- a/config/locales/devise/devise.de.yml
+++ b/config/locales/devise/devise.de.yml
@@ -19,6 +19,11 @@ de:
       timeout: "Deine Sitzung ist abgelaufen, bitte melde dich erneut an um fortzufahren."
       inactive: "Dein Konto wurde noch nicht aktiviert."
     sessions:
+      new:
+        login: 'Login'
+        username: 'Benutzername'
+        password: 'Passwort'
+        sign_in: 'Anmelden'
       signed_in: "Erfolgreich angemeldet."
       signed_out: "Erfolgreich abgemeldet."
     passwords:
@@ -34,7 +39,21 @@ de:
     unlocks:
       send_instructions: "Du wirst in ein paar Minuten eine E-Mail erhalten, die beschreibt, wie du dein Konto entsperren kannst."
       unlocked: "Dein Konto wurde erfolgreich entsperrt. Du bist nun angemeldet."
+    invitations:
+      send_instructions: 'Deine Einladung wurde versandt.'
+      invitation_token_invalid: 'Das Einladungstoken ist ungültig!' #FIXME: translate token?
+      updated: 'Dein Passwort wurde erfolgreich gesetzt. Du bist nun angemeldet.'
     mailer:
-      confirmation_instructions: "Instruktionen zur Bestätigung"
-      reset_password_instructions: "Instruktionen zum Zurücksetzen des Passworts"
-      unlock_instructions: "Instruktionen zum Entsperren"
+      confirmation_instructions:
+        subject: "Instruktionen zur Bestätigung"
+      reset_password_instructions:
+        subject: "Instruktionen zum Zurücksetzen des Passworts"
+      unlock_instructions:
+        subject: "Instruktionen zum Entsperren"
+      invitation:
+        subject: 'Ein Freund möchte dich bei Diaspora einladen!'
+    shared:
+      links:
+        sign_in: 'Anmelden'
+        sign_up: 'Registrieren'
+        forgot_your_password: 'Passwort vergessen?'
diff --git a/config/locales/diaspora/de.yml b/config/locales/diaspora/de.yml
index 1f7c028aee71a57acb75eb21252d2f922c6d8d99..5e257644c8d865947292f58a60d4143305e21980 100644
--- a/config/locales/diaspora/de.yml
+++ b/config/locales/diaspora/de.yml
@@ -2,206 +2,445 @@
 #   licensed under the Affero General Public License version 3 or later.  See
 #   the COPYRIGHT file.
 
-# Localization file for German. Add more files in this directory for other locales.
-# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
+#   Localization file for German
+#
+#   This file has parts from rails-i18n project at
+#        http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale
 
 de:
+  settings: "Einstellungen"
+  profile: "Profil"
+  account: "Konto"
+  services: "Dienste"
+  cancel: "Abbrechen"
+  delete: "Löschen"  
+  or: "oder"
+  by: "von"
+  ago: "her"
+  username: "Benutzername"
+  email: "E-Mail"
+  home: "Start"
+  password: "Passwort"
+  password_confirmation: "Passwort bestätigen"
+  are_you_sure: "Bist du sicher?"
+  
+  activemodel:
+      errors:
+          models:
+              user:
+                  attributes:
+                      person:
+                          invalid: "ist ungültig"
+                      username:
+                          taken: "ist bereits benutzt"
+                      email:
+                          taken: "ist bereits benutzt"
+              person:
+                  attributes:
+                      diaspora_handle:
+                          taken: "ist bereits benutzt"
   hello: "Hallo Welt"
   application:
       helper:
           unknown_person: "unbekannte Person"
-          new_requests: "neue Anfrage"
-  dashboards:
-      helper:
-          home: "Startseite"
+          new_requests: "neue Anfragen"
   error_messages:
       helper:
           invalid_fields: "Ungültige Felder"
-          correct_the_following_errors_and_try_again: "Korrigiere die folgenden Fehler und probiere es erneut."
-  people:
+          correct_the_following_errors_and_try_again: "Korrigiere die folgenden Fehler und versuche es erneut."
+  people: #FIXME: seems unused
       helper:
-           results_for: " Resultate für %{params}"
-           people_on_pod_are_aware_of: " people on pod are aware of"
+           results_for: " Ergebnisse für %{params}"
+           people_on_pod_are_aware_of: " Leute auf dem Pod sind aufmerksam auf"
   layouts:
       application:
+          view_profile: "Profil anzeigen"
           edit_profile: "Profil bearbeiten"
+          account_settings: "Konto Einstellungen"
+          search: "Suche"
           logout: "Abmelden"
   shared:
       aspect_nav:
           all_aspects: "Alle Aspekte"
           manage: "Verwalten"
-          manage_your_aspects: "Aspekte verwalten"
+          manage_your_aspects: "Deine Aspekte verwalten"
       sub_header:
           all_aspects: "Alle Aspekte"
           manage_aspects: "Aspekte verwalten"
       publisher:
           share: "Teilen"
+          post_a_message_to: "Sende eine Nachricht an %{aspect}"
+          make_public: "öffentlich machen"
       aspect_friends:
           add_friends: "Freunde hinzufügen"
+          photos: "Fotos"
+      invitations:
+          invites: 'Einladungen'
+          invite_a_friend: 'Freund einladen'
+          invitations_left: '(%{count} übrig)'
+      reshare:
+          reshare: 'Erneut senden an'
+      author_info:
+          view_profile: 'View profile'
   albums:
       album:
-          you: "dir"
+          you: "Du"
       new_album:
-          create: "erstellen"
+          create: "Hinzufügen"
           add_a_new_album: "Album hinzufügen"
       show:
           edit_album: "Album bearbeiten"
           albums: "Alben"
           updated: "aktualisiert"
-          by: "von"
       edit:
-          editing: "Bearbeite"
-          updated: "geändert"
-          are_you_sure: "Bist du sicher?"
+          album_name: "Name des Albums"
+          editing: "Bearbeiten"
+          updated: "aktualisiert"
+          update_album: "Album aktualisieren"
           delete_album: "Album löschen"
-          cancel: "Abbrechen"
       index:
-          home: "Startseite"
           new_album: "Neues Album"
       create:
           success: "Du hast das Album %{name} erstellt."
       update:
-          success: "Album %{name} erfolgreich geändert."
-          failure: "%{name} wurde nicht geändert."
+          success: "Album %{name} erfolgreich bearbeitet."
+          failure: "Bearbeiten des Album %{name} fehlgeschlagen."
       destroy:
           success: "Album %{name} gelöscht."
       helper:
           friends_albums: "Alben von Freunden"
           your_albums: "Deine Alben"
   aspects:
-      index:
-          photos: "Fotos"
-      show:
-          photos: "Fotos"
+      no_friends_message:
+          nobody: "Wir wissen du hast Freunde, hole sie an Bord!"
+          nobody_in_aspect: "Dein Aspekt %{aspect_name} ist leer."
+          add_friend: "Freund hinzufügen"
+          add_friend_to: "Jemanden zum Aspekt %{aspect_name} hinzufügen"
+          invite: "Jemanden zu Diaspora einladen!"
+      no_posts_message:
+          start_talking:  "Niemand hat bisher etwas gesagt. Beginne die Konversation!"
       manage:
-          add_a_new_aspect: "Neuen Aspekt erstellen"
-          add_a_new_friend:  "Freund hinzufügen"
-          show: "Anzeigen"
+          add_a_new_aspect: "Neuen Aspekt hinzufügen"
+          add_a_new_friend:  "Neuen Freund hinzufügen"
+          show: "Zeigen"
           update_aspects: "Aspekte aktualisieren"
           requests: "Anfragen"
           ignore_remove: "Ignorieren/Entfernen"
       new_aspect:
-          add_a_new_aspect: "Neuen Aspekt erstellen"
+          add_a_new_aspect: "Neuen Aspekt hinzufügen"
+          name: "Name"
           create: "Erstellen"
       create:
-          success: "Klicke auf das Plus auf der linken Seite um Diaspora mitzuteilen wer deinen neuen Aspekt sehen kann."
+          success: "Klicke auf das Plus auf der linken Seite um Diaspora zu sagen wer deinen neuen Aspekt sehen kann."
+          failure: "Erstellen des Aspekt fehlgeschlagen."
       destroy:
-          success: "%{name} wurde erfolgreich gelöscht."
+          success: "%{name} wurde erfolgreich entfernt."
       update:
-          success: "Dein Aspekt, %{name}, wurde erfolgreich geändert."
-      move_friends:
-          failure: "Ändern des Aspekts für deinen Freund %{real_name} fehlgeschlagen."
-          success: "Aspekt erfolgreich geändert."
+          success: "Dein Aspekt %{name} wurde erfolgreich bearbeitet."
       move_friend:
-          error: "didn't work %{inspect}"
-          notice: "Du zeigst deinem Freund jetzt einen anderen Aspekt von dir."
+          failure: "hat nicht funktioniert %{inspect}"
+          success: "Person zu neuem Aspekt verschoben"
+      add_to_aspect:
+          failure: "Hinzufügen des Freundes zum Aspekt fehlgeschlagen."
+          success: "Freund erfolgreich zum Aspekt hinzugefügt."
       helper:
           remove: "entfernen"
           aspect_not_empty: "Aspekt ist nicht leer"
   users:
       edit:
           editing_profile: "Profil bearbeiten"
-      profile:
-          cancel: "Abbrechen"
-          update_profile: "Profil aktualisieren"
-          home: "Startseite"
-          diaspora_username: "Diaspora Benutzername"
-          info: "Info"
-          picture: "Bild"
-          editing_profile: "Profil bearbeiten"
-          albums: "Alben"
-          you_dont_have_any_photos: "Du hast keine Fotos! Gehe auf die"
-          page_to_upload_some:  "Seite um welche hochzuladen."
+          invite_friends: "Feunde einladen"
+          export_data: "Konto exportieren"
+          close_account: "Konto schließen"
+          change_language: "Sprache ändern"
+          change_password: "Passwort ändern"
+          new_password: "Neues Passwort"
+      destroy: "Konto erfolgreich geschlossen."
+      getting_started:
+          signup_steps: "Vervollständige deine Registrierung indem du folgende Dinge tust:"
+          'step_1':
+              albums: "Alben"
+              you_dont_have_any_photos: "Du hast keine Fotos! Gehe zur"
+              page_to_upload_some:  "Seite um welche hochzuladen."
   comments:
-      comment:
-          # this won't work in german at all. Needs more thorough I18n
-          ago: "ago"
       new_comment:
-          comment: "Kommentar"
+          comment: "Kommentieren"
   photos:
       show:
           prev: "zurück"
           full_size: "volle Größe"
-          next: "vor"
+          next: "weiter"
           edit_photo: "Foto bearbeiten"
           delete_photo: "Foto löschen"
-          are_you_sure: "Bist du sicher?"
           comments: "Kommentare"
       edit:
-          editing: "Bearbeite"
-          are_you_sure: "Bist du sicher?"
+          editing: "Bearbeiten"
           delete_photo: "Foto löschen"
       photo:
-          show_comments: "Kommentare anzeigen"
-          posted_a_new_photo_to: "neues Foto veröffentlicht bei"
+          show_comments: "Kommentare zeigen"
+          posted_a_new_photo_to: "Hinzugefügt:"
       new:
-          new_photo: "Foto erstellen"
-          back_to_list: "Zurück zur Liste"
-          post_it: "Hochladen"
+          new_photo: "Neues Foto"
+          back_to_list: "Zurück zu Liste"
+          post_it: "Poste es!"
       create:
-          runtime_error: "Hochladen eines Fotos fehlgeschlagen. Bist du sicher, dass dein Sicherheitsgurt befestigt ist?"
-          integrity_error: "Hochladen eines Fotos fehlgeschlagen.  Bist du sicher, dass das ein Bild war?"
-          type_error: "Hochladen eines Fotos fehlgeschlagen.  Bist du sicher, dass ein Bild hinzugefügt wurde?"
+          runtime_error: "Der Server wollte das Foto nicht bearbeiten, bist du darauf zu sehen?"
+          integrity_error: "Hochladen des Fotos fehlgeschlagen. Bist du sicher das es ein Foto war?"
+          type_error: "Hochladen des Foto fehlgeschlagen. Du solltest hier nur FOTOS hochladen..."
       update:
           notice: "Foto erfolgreich aktualisiert."
-          error:  "Ändern des Fotos fehlgeschlagen."
+          error:  "Bearbeiten des Fotos fehlgeschlagen."
       destroy:
           notice: "Foto gelöscht."
   registrations:
       new:
-          sign_up: "Anmelden"
+          sign_up: "Registrieren"
+          sign_up_for_diaspora: "Ein Diaspora Konto anlegen"
+          upload_existing_account: "Ein existierendes Konto hochladen"
+          upload: "Hochladen"
+      create:
+          success: "Willkommen bei Diaspora!"
+  invitations:
       create:
-          success: "Du bist Diaspora beigetreten!"
+          sent: 'Deine Einladung wurde verschickt.'
+          no_more: 'Du hast keine Einladungen mehr.'
+          already_sent: 'Du hast diese Person bereits eingeladen.'
+          already_friends: 'Du bist bereits mit dieser Person befreundet'
+          invitation_token_invalid: 'Das Einladungstoken ist ungültig!'
+          updated: 'Dein Passwort wurde erfolgreich gespeichert. Du bist jetzt angemeldet.'
+      new:
+          invite_someone_to_join: 'Lade jemanden zu Diaspora ein!'
+          if_they_accept_info: 'Wenn sie akzeptieren findest du sie im Aspekt in den du sie eingeladen hast'
+          to: 'An'
+          message: 'Nachricht:'
+          send_an_invitation: 'Eine Einladung senden'
+          send_invitation: 'Einladung senden'
+
   status_messages:
-      new_status_message:
-          tell_me_something_good: "Erzähl' mir was schönes!"
-          oh_yeah: "Oh, super!"
+      new_status_message: #FIXME: seems unused
+          tell_me_something_good: "Was gibt es neues?"
+          oh_yeah: "oh yeah!"
       status_message:
-          show_comments: "Kommentare anzeigen"
-          delete: "Löschen"
-          are_you_sure: "Bist du sicher?"
+          show_comments: "Kommentare zeigen"
       show:
-          status_message: "Statusmeldung"
+          status_message: "Status Nachricht"
           comments: "Kommentare"
-          are_you_sure: "Bist du sicher?"
-          destroy: "Löschen"
-          view_all: "Alle anzeigen"
+          destroy: "Zerstören"
+          view_all: "Alle zeigen"
           message: "Nachricht"
-          owner: "Eigentümer"
+          owner: "Besitzer"
       helper:
           no_message_to_display: "Keine Nachricht zum anzeigen."
   people:
       person:
           add_friend: "Freund hinzufügen"
-          pending_request: "Anfrage ausstehend"
+          pending_request: "Ausstehende Anfrage"
       index:
           add_friend: "Freund hinzufügen"
-          real_name: "Echter Name"
-          diaspora_handle: "diaspora handle"
-          thats_you: "das bist du!"
-          friend_request_pending: "Ausstehende Freundschaftsanfrage"
-          you_have_a_friend_request_from_this_person: "Du hast eine Freundschaftsanfrage von dieser Person"
+          real_name: "Realer Name"
+          diaspora_handle: "Diaspora Adresse"
+          thats_you: "Das bist du!"
+          friend_request_pending: "Ausstehende Freundes-Anfrage"
+          you_have_a_friend_request_from_this_person: "Du hast eine Freundes-Anfrage von dieser Person"
       new:
           new_person: "Neue Person"
           back_to_list: "Zurück zur Liste"
       show:
-          last_seen: "zuletzt gesehen: %{how_long_ago}"
+          last_seen: "Zuletzt gesehen vor: %{how_long_ago}" #FIXME: appends ago
           friends_since: "Freunde seit: %{how_long_ago}"
           save: "speichern"
-          are_you_sure: "Bist du sicher?"
           remove_friend: "Freund entfernen"
+          no_posts: "Keine Posts zum anzeigen!"
+          add_friend: "Freund hinzufügen"
+          edit_my_profile: "Mein Profil bearbeiten"
+      edit:
+          info_available_to: "Diese Infos werden für alle verfügbar sein mit denen du bei Diaspora verbunden bist."
+          your_profile: "Dein Profil"
+          your_name: "Dein Name"
+          first_name: "Vorname"
+          last_name: "Nachname"
+          your_gender: "Dein Geschlecht"
+          your_birthday: "Dein Geburtstag"
+          your_bio: "Deine Info"
+          fill_me_out: "Füll mich aus"
+          your_photo: "Dein Foto"
+          update_profile: "Profil aktualisieren"
+          diaspora_username: "DIASPORA ADRESSE"
+          info: "Info"
+          picture: "Bild"
+          editing_profile: "Profil bearbeiten"
+          albums: "Alben"
+          you_dont_have_any_photos: "Du hast keine Fotos! Gehe zur"
+          page_to_upload_some:  "Seite um welche hochzuladen."
   requests:
       new_request:
-          add_a_new_friend_to: "Add a new friend to"
-          enter_a_diaspora_username: "Gebe einen Diaspora Benutzernamen ein:"
-          your_diaspora_username_is: "Dein Diaspora Benutzername ist: %{diaspora_handle}"
-          friends_username: "Freundes Benutzername"
+          add_a_new_friend_to: "Neuen Freund hinzufügen zu"
+          enter_a_diaspora_username: "Gib eine Diaspora Adresse ein:"
+          your_diaspora_username_is: "Deine Diaspora Adresse ist: %{diaspora_handle}"
+          friends_username: "Diaspora Addresse deines Freundes"
+          create_request: "Anfrage erstellen"
       destroy:
-          success: "Ihr seid jetzt Freunde."
-          error: "Bitte wähle einen Aspekt aus!"
-          ignore: "Freundschaftsanfrage ignorieren."
+          success: "Ihr seit jetzt Freunde."
+          error: "Bitte wähle einen Aspekt!"
+          ignore: "Freundes-Anfrage ignoriert."
       create:
-          error: "Kein Diaspora-Seed in dieser E-Mail gefunden!"
+          error: "Keinen Diaspora Seed mit dieser E-Mail gefunden!" #FIXME: wtf?
+          invalid_identity: "Diese Diaspora Adresse ist nicht richtig formatiert"
+          error_server: "Problem mit dem anderen Server. Vielleicht existiert er nicht?"
+          yourself: "Du kannst dich nicht mit dir selbst befreunden!"
           already_friends: "Du bist bereits mit %{destination_url} befreundet!"
-          success: "Eine Freundschaftsanfrage wurde an %{destination_url} gesendet."
-          horribly_wrong: "Etwas ging tierisch schief."
+          success: "Eine Freundes-Anfrage wurde an %{destination_url} geschickt."
+          horribly_wrong: "Irgendwas ist furchtbar schief gelaufen."
+
+# The following is from the rails-i18n project at http://github.com/svenfuchs/rails-i18n
+
+# German translations for Ruby on Rails
+# by Clemens Kofler (clemens@railway.at)
+
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%e. %b"
+      long: "%e. %B %Y"
+      only_day: "%e"
+
+    day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
+    abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
+    month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
+    abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
+    order: [ :day, :month, :year ]
+
+  time:
+    formats:
+      default: "%A, %d. %B %Y, %H:%M Uhr"
+      short: "%d. %B, %H:%M Uhr"
+      long: "%A, %d. %B %Y, %H:%M Uhr"
+      time: "%H:%M"
+
+    am: "vormittags"
+    pm: "nachmittags"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: 'eine halbe Minute'
+      less_than_x_seconds:
+        one: 'weniger als eine Sekunde'
+        other: 'weniger als %{count} Sekunden'
+      x_seconds:
+        one: 'eine Sekunde'
+        other: '%{count} Sekunden'
+      less_than_x_minutes:
+        one: 'weniger als eine Minute'
+        other: 'weniger als %{count} Minuten'
+      x_minutes:
+        one: 'eine Minute'
+        other: '%{count} Minuten'
+      about_x_hours:
+        one: 'etwa eine Stunde'
+        other: 'etwa %{count} Stunden'
+      x_days:
+        one: 'ein Tag'
+        other: '%{count} Tage'
+      about_x_months:
+        one: 'etwa ein Monat'
+        other: 'etwa %{count} Monate'
+      x_months:
+        one: 'ein Monat'
+        other: '%{count} Monate'
+      almost_x_years:
+        one: 'fast ein Jahr'
+        other: 'fast %{count} Jahre'
+      about_x_years:
+        one: 'etwa ein Jahr'
+        other: 'etwa %{count} Jahre'
+      over_x_years:
+        one: 'mehr als ein Jahr'
+        other: 'mehr als %{count} Jahre'
+    prompts:
+      second: "Sekunden"
+      minute: "Minuten"
+      hour: "Stunden"
+      day: "Tag"
+      month: "Monat"
+      year: "Jahr"
+
+  number:
+    format:
+      precision: 2
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: '€'
+        format: '%n%u'
+        separator: ","
+        delimiter: ""
+        precision: 2
+    percentage:
+      format:
+        delimiter: ""
+    precision:
+      format:
+        delimiter: ""
+    human:
+      format:
+        delimiter: ""
+        precision: 1
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " und "
+      last_word_connector: " und "
+    select:
+      prompt: "Bitte wählen:"
+
+  activemodel:
+    errors:
+      template:
+        header:
+          one:    "Konnte %{model} nicht speichern: ein Fehler."
+          other:  "Konnte %{model} nicht speichern: %{count} Fehler."
+        body: "Bitte überprüfen Sie die folgenden Felder:"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "Konnte %{model} nicht speichern: ein Fehler."
+          other:  "Konnte %{model} nicht speichern: %{count} Fehler."
+        body: "Bitte überprüfen Sie die folgenden Felder:"
+
+      messages:
+        inclusion: "ist kein gültiger Wert"
+        exclusion: "ist nicht verfügbar"
+        invalid: "ist nicht gültig"
+        confirmation: "stimmt nicht mit der Bestätigung überein"
+        accepted: "muss akzeptiert werden"
+        empty: "muss ausgefüllt werden"
+        blank: "muss ausgefüllt werden"
+        too_long: "ist zu lang (nicht mehr als %{count} Zeichen)"
+        too_short: "ist zu kurz (nicht weniger als %{count} Zeichen)"
+        wrong_length: "hat die falsche Länge (muss genau %{count} Zeichen haben)"
+        taken: "ist bereits vergeben"
+        not_a_number: "ist keine Zahl"
+        greater_than: "muss größer als %{count} sein"
+        greater_than_or_equal_to: "muss größer oder gleich %{count} sein"
+        equal_to: "muss genau %{count} sein"
+        less_than: "muss kleiner als %{count} sein"
+        less_than_or_equal_to: "muss kleiner oder gleich %{count} sein"
+        odd: "muss ungerade sein"
+        even: "muss gerade sein"
+        record_invalid: "Gültigkeitsprüfung ist fehlgeschlagen: %{errors}"
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index 3a9de1b7c58702c7477daabccdbd2817df125c62..582cc170a9b29731ddffd04064078cb65d4a8910 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -101,6 +101,7 @@ en:
           new_album: "New Album"
       create:
           success: "You've created an album called %{name}."
+          failure: "Failed to create album."
       update:
           success: "Album %{name} successfully edited."
           failure: "Failed to edit album %{name}."
diff --git a/config/routes.rb b/config/routes.rb
index 8604abaad7decbccee623fd97e713e6b2ee93c13..3bd37a018142c0065a2a4b6a5235cfa41dc26a23 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -20,7 +20,6 @@ Diaspora::Application.routes.draw do
   match 'public/:username',          :to => 'users#public'
   match 'getting_started',           :to => 'users#getting_started', :as => 'getting_started'
   match 'users/export',              :to => 'users#export'
-  match 'users/import',              :to => 'users#import'
   match 'users/export_photos',       :to => 'users#export_photos'
   resources :users,                  :except => [:create, :new, :show]
 
diff --git a/config/sprinkle/conf/nginx.conf b/config/sprinkle/conf/nginx.conf
index 68eff160678a81603c140b9b1cb2692885762a8d..724645292051a4c9a255595eaffef4c97d8750d5 100644
--- a/config/sprinkle/conf/nginx.conf
+++ b/config/sprinkle/conf/nginx.conf
@@ -27,8 +27,9 @@ http {
  gzip_comp_level   2;
  gzip_proxied      any;
  gzip_buffers      16 8k;
- #gzip_types        text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
- # gzip_disable      "MSIE [1-6]\.(?!.*SV1)";
+ gzip_types        text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
+ gzip_disable      "MSIE [1-6]\.(?!.*SV1)";
+
   upstream thin_cluster {
   server unix:/tmp/thin.0.sock;
   server unix:/tmp/thin.1.sock;
@@ -46,7 +47,6 @@ http {
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
-    proxy_buffering off;
 
     if (-f $request_filename/index.html) {
       rewrite (.*) $1/index.html break;
diff --git a/lib/diaspora/importer.rb b/lib/diaspora/importer.rb
deleted file mode 100644
index 57dd11ae9d0f1a5d9e14090a8fe46eff63b1a0d8..0000000000000000000000000000000000000000
--- a/lib/diaspora/importer.rb
+++ /dev/null
@@ -1,222 +0,0 @@
-#   Copyright (c) 2010, Diaspora Inc.  This file is
-#   licensed under the Affero General Public License version 3 or later.  See
-#   the COPYRIGHT file.
-
-module Diaspora
-
-  class Importer
-    def initialize(strategy)
-      self.class.send(:include, strategy)
-    end
-    
-    def commit(user, person, aspects, people, posts, contacts, opts = {})
-      filter = verify_and_clean(user, person, people, aspects, posts, contacts)
-  
-      #assume data is good
-      
-      # to go 
-      user.email = opts[:email]
-      user.password= opts[:password]
-      user.password_confirmation = opts[:pasword_confirmation]
-
-     
-     
-      user.person = person
-
-
-      user.person.diaspora_handle = opts[:diaspora_handle] 
-      
-      user.visible_post_ids = filter[:whitelist].keys
-
-      #user.friend_ids =       
-      user.visible_person_ids = people.collect{ |x| x.id }
-
-      
-      posts.each do |post|
-        post.save! if filter[:unknown].include? post.id
-      end
-
-
-
-      aspects.each do |aspect|
-        user.aspects << aspect
-      end
-
-      people.each do |p|
-        p.save! if filter[:people].include? p.id.to_s
-      end
-
-      contacts.each do |contact|
-        contact.user = user
-
-        user.friends << contact
-        contact.save!
-      end
-
-
-      puts user.persisted?
-
-      puts user.inspect
-      user.save(:validate => false)
-
-
-    end
-
-    def assign_aspect_ids(contacts, aspects)
-      a_hash = {}
-      aspects.each{|x| a_hash[x.name]=x.id}
-
-      contacts.each do |contact|
-        contact.aspect_names.each  do |x|
-          contact.aspect_ids << a_hash[x]
-        end
-        contact.aspect_names = nil
-      end
-
-
-    end
-
-    ### verification (to be module) ################
-
-    def verify_and_clean(user, person, people, aspects, posts, contacts)
-      verify_user(user)
-      verify_person_for_user(user, person)
-      filters = filter_posts(posts, person)
-      clean_aspects(aspects, filters[:whitelist])
-      filters[:all_person_ids] = people.collect{ |x| x.id.to_id }
-
-      raise "incorrect number of contacts" unless verify_contacts(contacts, filters[:all_person_ids])
-      assign_aspect_ids(contacts, aspects)
-      filters[:people] = filter_people(people)
-      filters  
-    end
-
-    def verify_contacts(contacts, person_ids)
-      return false if contacts.count != person_ids.count
-      contacts.all?{|x| person_ids.include?(x.person_id)} 
-    end
- 
-    def verify_user(user)
-      User.find_by_id(user.id).nil? ? true : raise("User already exists!")
-    end
-
-    def verify_person_for_user(user, person)
-      local_person = Person.find_by_id(person.id)
-      if local_person
-        unless user.encryption_key.public_key.to_s == local_person.public_key.to_s
-          raise "local person found with different owner" 
-        end
-      end
-      true
-    end
-
-
-    def filter_people(people)
-      person_ids = people.collect{|x| x.id}
-      people_from_db = Person.find_all_by_id(person_ids)  #this query should be limited to only return person_id
-      person_ids = person_ids - people_from_db.collect{ |x| x.id }
-
-      person_hash = {}
-      person_ids.each{|x| person_hash[x.to_s] = true }  
-      person_hash
-    end
-
-    def filter_posts(posts, person)
-      post_ids = posts.collect{|x| x.id}
-      posts_from_db = Post.find_all_by_id(post_ids)  #this query should be limited to only return post id and owner id
- 
-      unknown_posts = post_ids - posts_from_db.collect{|x| x.id}
-
-      posts_from_db.delete_if{|x| x.person_id == person.id}
-      unauthorized_post_ids = posts_from_db.collect{|x| x.id}
-      post_whitelist = post_ids - unauthorized_post_ids
-
-      unknown = {}
-      unknown_posts.each{|x| unknown[x.to_s] = true }
-      
-      whitelist = {}
-      post_whitelist.each{|x| whitelist[x.to_s] = true }
-      
-      return {
-          :unknown => unknown,
-          :whitelist => whitelist }
-    end
-
-
-    def clean_aspects(aspects, whitelist)
-      aspects.each do |aspect|
-        aspect.post_ids.delete_if{ |x| !whitelist.include? x.to_s }
-      end
-    end
-  end
-
-  module Parsers
-    module XML
-      def execute(xml, opts = {})
-        doc = Nokogiri::XML.parse(xml)
-
-        user, person = parse_user_and_person(doc)
-        aspects = parse_aspects(doc)
-        contacts = parse_contacts(doc)
-        people = parse_people(doc)
-        posts = parse_posts(doc)
-      
-        user
-        commit(user, person, aspects, people, posts, contacts, opts)
-      end
-
-      def parse_user_and_person(doc)
-        user = User.new
-        user_doc = doc.xpath('/export/user')
-        user.username = user_doc.xpath('//user/username').text
-        user.serialized_private_key=  user_doc.xpath('//user/serialized_private_key').text
-        person = Person.from_xml(user_doc.xpath('//user/person').to_s)
-        [user, person]
-      end
-
-      def parse_aspects(doc)
-       aspects = []
-        aspect_doc = doc.xpath('/export/aspects/aspect')
-
-        aspect_doc.each do |x| 
-          a = Nokogiri::XML.parse(x.to_s)
-
-          aspect = Aspect.new
-          aspect.name = a.xpath('/aspect/name').text
-          aspect.post_ids = a.xpath('/aspect/post_ids/post_id').collect{ |x| x.text.to_id }
-          aspects << aspect
-        end
-        aspects
-      end
-
-      def parse_people(doc)
-        people_doc = doc.xpath('/export/people/person')
-        people_doc.inject([]) do |people,curr|
-          people << Person.from_xml(curr.to_s)
-        end
-      end
-
-      def parse_contacts(doc)
-        contacts = []
-        contact_doc = doc.xpath('/export/contacts/contact') 
-
-        contact_doc.each do |x|
-          contact = Contact.new
-          contact.person_id = x.xpath("person_id").text.to_id
-          contact.aspect_names = x.xpath('aspects/aspect/name').collect{ |x| x.text}
-          contacts << contact
-        end
-        contacts
-      end
-
-      def parse_posts(doc)
-        post_doc = doc.xpath('/export/posts/status_message')
-        post_doc.inject([]) do |posts,curr|
-          posts << StatusMessage.from_xml(curr.to_s)
-        end
-      end
-
-    end
-
-  end
-end
diff --git a/lib/diaspora/parser.rb b/lib/diaspora/parser.rb
index acdd27afdaf4009fa648017cda6d1293bb12e56e..da3344d84d61c2653b2035cd57124efb206decb0 100644
--- a/lib/diaspora/parser.rb
+++ b/lib/diaspora/parser.rb
@@ -10,14 +10,7 @@ module Diaspora
 
       begin
         new_object = body.name.camelize.constantize.from_xml body.to_s
-
-        if new_object.is_a? Post
-          existing_object = new_object.class.find_by_id(new_object.id)
-          existing_object ? (return existing_object) : (return new_object)
-        end
-
-        new_object
-
+        return new_object
       rescue NameError => e
         if e.message.include? 'wrong constant name'
           Rails.logger.info "Not a real type: #{object.to_s}"
diff --git a/lib/diaspora/user/receiving.rb b/lib/diaspora/user/receiving.rb
index 9e9da020c22b17dc5002f3d6658f2b896b11e9b0..e0dd3ef8646cbc70791f243149f403b17e671000 100644
--- a/lib/diaspora/user/receiving.rb
+++ b/lib/diaspora/user/receiving.rb
@@ -7,10 +7,15 @@ module Diaspora
         salmon = Salmon::SalmonSlap.parse salmon_xml, self
         webfinger = EMWebfinger.new(salmon.author_email)
 
-        webfinger.on_person { |salmon_author|
-          if salmon.verified_for_key?(salmon_author.public_key)
-            Rails.logger.info("data in salmon: #{salmon.parsed_data}")
-            self.receive(salmon.parsed_data, salmon_author)
+        webfinger.on_person { |response|
+          if response.is_a? Person
+            salmon_author = response
+            if salmon.verified_for_key?(salmon_author.public_key)
+              Rails.logger.info("data in salmon: #{salmon.parsed_data}")
+              self.receive(salmon.parsed_data, salmon_author)
+            end
+          else
+            Rails.logger.info("#{salmon.author_email} not found error: #{response}")
           end
         }
       end
@@ -45,13 +50,13 @@ module Diaspora
               raise "Not friends with that person" unless self.contact_for(salmon_author)
 
               if object.is_a?(Comment) 
-                receive_comment object, xml
+                receive_comment object
               elsif object.is_a?(Retraction)
-                receive_retraction object, xml
+                receive_retraction object
               elsif object.is_a?(Profile)
                 receive_profile object, person
               else
-                receive_post object, xml
+                receive_post object
               end
             end
           }
@@ -60,7 +65,7 @@ module Diaspora
         end
       end
 
-      def receive_retraction retraction, xml
+      def receive_retraction retraction
         if retraction.type == 'Person'
           unless retraction.person.id.to_s == retraction.post_id.to_s
             raise "#{retraction.diaspora_handle} trying to unfriend #{retraction.post_id} from #{self.id}"
@@ -91,7 +96,7 @@ module Diaspora
         person.save
       end
 
-      def receive_comment comment, xml
+      def receive_comment comment
         raise "In receive for #{self.real_name}, signature was not valid on: #{comment.inspect}" unless comment.post.person == self.person || comment.verify_post_creator_signature
         self.visible_people = self.visible_people | [comment.person]
         self.save
@@ -105,7 +110,39 @@ module Diaspora
         comment.socket_to_uid(id)  if (comment.respond_to?(:socket_to_uid) && !self.owns?(comment))
       end
 
-      def receive_post post, xml
+      def exsists_on_pod?(post)
+        post.class.find_by_id(post.id)
+      end
+
+      def receive_post post
+        #exsists locally, but you dont know about it
+        #does not exsist locally, and you dont know about it
+        
+        #exsists_locally?
+          #you know about it, and it is mutable
+          #you know about it, and it is not mutable
+        #
+        on_pod = exsists_on_pod?(post)
+        if on_pod && on_pod.diaspora_handle == post.diaspora_handle 
+          known_post = find_visible_post_by_id(post.id)
+          if known_post 
+            if known_post.mutable?
+              known_post.update_attributes(post.to_mongo)
+            else
+              Rails.logger.info("#{post.diaspora_handle} is trying to update an immutable object #{known_post.inspect}")
+            end
+          elsif on_pod == post 
+            update_user_refs_and_add_to_aspects(on_pod)
+          end
+        elsif !on_pod 
+          update_user_refs_and_add_to_aspects(post)
+        else
+          Rails.logger.info("#{post.diaspora_handle} is trying to update an exsisting object they do not own #{on_pod.inspect}")
+        end
+      end
+
+
+      def update_user_refs_and_add_to_aspects(post)
         Rails.logger.debug("Saving post: #{post}")
         post.user_refs += 1
         post.save
@@ -114,11 +151,13 @@ module Diaspora
         self.save
 
         aspects = self.aspects_with_person(post.person)
-        aspects.each{ |aspect|
+        aspects.each do |aspect|
           aspect.posts << post
           aspect.save
-          post.socket_to_uid(id, :aspect_ids => [aspect.id]) if (post.respond_to?(:socket_to_uid) && !self.owns?(post))
-        }
+        end
+
+        post.socket_to_uid(id, :aspect_ids => aspects.map{|x| x.id}) if (post.respond_to?(:socket_to_uid) && !self.owns?(post))
+
       end
     end
   end
diff --git a/lib/diaspora/websocket.rb b/lib/diaspora/websocket.rb
index 09c553e20c86ce30f8ab37c66a16e4c167297ea8..2fec38d397c314a5f409b3bf7e7b38f8efa0bddf 100644
--- a/lib/diaspora/websocket.rb
+++ b/lib/diaspora/websocket.rb
@@ -15,7 +15,7 @@ module Diaspora
 
     def self.push_to_user(uid, data)
       Rails.logger.debug "Websocketing to #{uid}"
-      @channels[uid.to_s][0].push(data) if @channels[uid.to_s]
+      @channels[uid][0].push(data) if @channels[uid]
     end
 
     def self.subscribe(uid, ws)
diff --git a/lib/hcard.rb b/lib/hcard.rb
index 5fd60b182c2e1da0b74223fbccc959a44d887d5c..09acb7c8f938c883b119e83b5e388c2caeb8de1e 100644
--- a/lib/hcard.rb
+++ b/lib/hcard.rb
@@ -3,23 +3,16 @@
 #   the COPYRIGHT file.
 
 module HCard
-  def self.fetch url
-    Nokogiri::HTML(Net::HTTP.get URI.parse(url))
-  end
-
   def self.parse doc
     {
-      :given_name => doc.css(".given_name").text,
+      :given_name  => doc.css(".given_name").text,
       :family_name => doc.css(".family_name").text,
-      :url => doc.css("#pod_location").text,
-      :photo => doc.css(".photo[src]").attribute('src').text     
+      :url         => doc.css("#pod_location").text,
+      :photo       => doc.css(".photo[src]").attribute('src').text,
+      :searchable  => doc.css(".searchable").text
     }
   end
 
-  def self.find url
-    self.parse self.fetch(url)
-  end
-
   def self.build(raw_hcard)
     self.parse Nokogiri::HTML(raw_hcard)
   end
diff --git a/public/images/diaspora_white_on_grey.png b/public/images/diaspora_white_on_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..6213e06712dd37b1c841e55ef4dc7bd85d1e778f
Binary files /dev/null and b/public/images/diaspora_white_on_grey.png differ
diff --git a/public/javascripts/aspect-edit.js b/public/javascripts/aspect-edit.js
index c4e05d7d0051d2d6040aa46478cc4cece5576dae..8346bb7dd9fc9a0019384674798df43d30884447 100644
--- a/public/javascripts/aspect-edit.js
+++ b/public/javascripts/aspect-edit.js
@@ -1,160 +1,169 @@
 /*   Copyright (c) 2010, Diaspora Inc.  This file is
-*   licensed under the Affero General Public License version 3 or later.  See
-*   the COPYRIGHT file.
-*/
-
-function decrementRequestsCounter() {
-  var $new_requests     = $(".new_requests");
-  var request_html      = $new_requests.html();
-  var old_request_count = request_html.match(/\d+/);
-
-  if( old_request_count == 1 ) {
-    $new_requests.html(
-      request_html.replace(/ \(\d+\)/,'')
-    );
-  } else {
-    $new_requests.html(
-      request_html.replace(/\d+/,old_request_count-1)
-    );
-  }
-}
-
-// Dragging person between aspects
-$(function() {
-  $("ul .person").draggable({
-    revert: true,
-    start: function(event,ui){
-      $(this).children("img").animate({'height':80, 'width':80, 'opacity':0.8},200)
-             .tipsy("hide");
-      $(".draggable_info").fadeIn(100);
-    },
-    drag: function(event,ui){
-      $(this).children("img").tipsy("hide"); //ensure this is hidden
-    },
-    stop: function(event,ui){
-      $(this).children("img").animate({'height':70, 'width':70, 'opacity':1},200);
-      $(".draggable_info").fadeOut(100);
-    }
-  });
-
-  $(".aspect ul.dropzone").droppable({
-    hoverClass: 'active',
-    drop: function(event, ui) {
-
-      var dropzone = $(this);
-      var person   = ui.draggable;
-
-      if( person.hasClass('request') ){
-        $.ajax({
-          type: "DELETE",
-          url: "/requests/" + person.attr('data-guid'),
-          data: {"accept" : true, "aspect_id" : dropzone.attr('data-aspect_id') },
-          success: function(data){
-            decrementRequestsCounter();
-          }
-        });
-      };
-
+ *   licensed under the Affero General Public License version 3 or later.  See
+ *   the COPYRIGHT file.
+ */
+
+var AspectEdit = {
+
+  initialize: function() {
+    $("ul .person").draggable({
+      revert: true,
+      start: AspectEdit.startDrag,
+      drag: AspectEdit.duringDrag,
+      stop: AspectEdit.stopDrag
+    });
 
-      if( dropzone.attr('data-aspect_id') != person.attr('data-aspect_id' )){
-        $.ajax({
-          url: "/aspects/move_friend/",
-          data: {"friend_id" : person.attr('data-guid'),
-                 "from"      : person.attr('data-aspect_id'),
-                 "to"        : { "to" : dropzone.attr('data-aspect_id') }},
-          success: function(data){
-            person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
-          }});
-        }
+    $(".aspect ul.dropzone").droppable({
+      hoverClass: 'active',
+      drop: AspectEdit.onDropMove
+    });
 
-      dropzone.closest("ul").append(person);
-    }
-  });
+    $(".aspect_remove ul").droppable({
+      hoverClass: 'active',
+      drop: AspectEdit.onDropDelete
+    });
 
+    $(".delete").live("click", AspectEdit.deletePerson);
+    $(".aspect h3").live('focus', AspectEdit.changeName);
+  },
 
-  $(".aspect_remove ul").droppable({
-    hoverClass: 'active',
-    drop: function(event, ui) {
+  startDrag: function(event, ui) {
+    $(this).children("img").animate({'height':80, 'width':80, 'opacity':0.8}, 200)
+      .tipsy("hide");
+    $(".draggable_info").fadeIn(100);
+  },
 
-      var person = ui.draggable;
+  duringDrag: function(event, ui) {
+    $(this).children("img").tipsy("hide"); //ensure this is hidden
+  },
 
-      if ( person.attr('data-guid').length == 1 ) {
-        alert("You can not remove the person from the last aspect");
+  stopDrag: function(event, ui) {
+    $(this).children("img").animate({'height':70, 'width':70, 'opacity':1}, 200);
+    $(".draggable_info").fadeOut(100);
+  },
 
-      } else {
-        if( !person.hasClass('request') ){
+  onDropMove: function(event, ui) {
+    var dropzone = $(this);
+    var person = ui.draggable;
 
-          $.ajax({
-            type: "POST",
-            url: "/aspects/remove_from_aspect",
-            data:{
-                  'friend_id' : person.attr('data-guid'),
-                  'aspect_id' : person.attr('data-aspect_id') }
-          });
+    if (person.hasClass('request')) {
+      $.ajax({
+        type: "DELETE",
+        url: "/requests/" + person.attr('data-guid'),
+        data: {"accept" : true, "aspect_id" : dropzone.attr('data-aspect_id') },
+        success: function(data) {
+          AspectEdit.decrementRequestsCounter();
         }
-      person.fadeOut(400, function(){person.remove();});
-      }
+      });
+    }
+
+    if (dropzone.attr('data-aspect_id') != person.attr('data-aspect_id')) {
+      $.ajax({
+        url: "/aspects/move_friend/",
+        data: {"friend_id" : person.attr('data-guid'),
+          "from"      : person.attr('data-aspect_id'),
+          "to"        : { "to" : dropzone.attr('data-aspect_id') }},
+        success: function(data) {
+          person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
+        }});
     }
-  });
-});
 
+    dropzone.closest("ul").append(person);
+  },
 
-// Person deletion
-$(".delete").live("click", function() {
+  onDropDelete: function(event, ui) {
+    var person = ui.draggable;
 
-  var person = $(this).closest("li.person");
+    if (person.attr('data-guid').length == 1) {
+      alert("You can not remove the person from the last aspect");
 
-  if (person.hasClass('request')){
-    if( confirm("Ignore request?") ){
-      var request_id = person.attr("data-guid");
+    } else {
+      if (!person.hasClass('request')) {
 
-      $.ajax({
-        type: "DELETE",
-        url: "/requests/" + request_id,
-        success: function () {
-          decrementRequestsCounter();
-        }
+        $.ajax({
+          type: "POST",
+          url: "/aspects/remove_from_aspect",
+          data:{
+            'friend_id' : person.attr('data-guid'),
+            'aspect_id' : person.attr('data-aspect_id') }
+        });
+      }
+      person.fadeOut(400, function() {
+        person.remove();
       });
     }
+  },
 
-  } else {
-    if( confirm("Remove this person from all aspects?") ){
-      var person_id = $(this).closest("li.person").attr('data-guid');
+  changeName:  function() {
 
-      $.ajax({
-        type: "DELETE",
-        url: "/people/" + person_id,
-        success: function() {
-          person.fadeOut(200);
-        }
-      });
-    }
-  }
-});
+    var $this = $(this);
+    var id = $this.closest("li.aspect").attr("data-guid");
+    var link = "/aspects/" + id;
 
+    $this.keypress(function(e) {
+      if (e.which == 13) {
+        e.preventDefault();
+        $this.blur();
 
-// Editing aspect name
-$(".aspect h3").live('focus', function() {
+        //save changes
+        $.ajax({
+          type: "PUT",
+          url: link,
+          data: {"aspect" : {"name" : $this.text() }}
+        });
+      }
+      //update all other aspect links
+      $this.keyup(function(e) {
+        $("#aspect_nav a[href='" + link + "']").text($this.text());
+      });
+    });
+  },
 
-  var $this = $(this);
-  var id    = $this.closest("li.aspect").attr("data-guid");
-  var link  = "/aspects/"+ id;
+  deletePerson: function() {
+    var person = $(this).closest("li.person");
 
-  $this.keypress(function(e) {
-    if (e.which == 13) {
-      e.preventDefault();
-      $this.blur();
+    if (person.hasClass('request')) {
+      if (confirm("Ignore request?")) {
+        var request_id = person.attr("data-guid");
 
-      //save changes
-      $.ajax({
-        type: "PUT",
-        url: link,
-        data: {"aspect" : {"name" : $this.text() }}
-      });
+        $.ajax({
+          type: "DELETE",
+          url: "/requests/" + request_id,
+          success: function () {
+            AspectEdit.decrementRequestsCounter();
+          }
+        });
+      }
+    } else {
+      if (confirm("Remove this person from all aspects?")) {
+        var person_id = $(this).closest("li.person").attr('data-guid');
+
+        $.ajax({
+          type: "DELETE",
+          url: "/people/" + person_id,
+          success: function() {
+            person.fadeOut(200);
+          }
+        });
+      }
     }
-    //update all other aspect links
-    $this.keyup(function(e) {
-      $("#aspect_nav a[href='"+link+"']").text($this.text());
-    });
-  });
-});
+  },
+
+  decrementRequestsCounter: function() {
+    var $new_requests = $(".new_requests");
+    var request_html = $new_requests.html();
+    var old_request_count = request_html.match(/\d+/);
+
+    if (old_request_count == 1) {
+      $new_requests.html(
+        request_html.replace(/ \(\d+\)/, '')
+        );
+    } else {
+      $new_requests.html(
+        request_html.replace(/\d+/, old_request_count - 1)
+        );
+    }
+  }
+};
+
+$(document).ready(AspectEdit.initialize);
\ No newline at end of file
diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass
index c541f5c417044a000c814a11c51c3c7f0681a936..5577d829f6b2c44b7743bff6766ba95a5a16ab11 100644
--- a/public/stylesheets/sass/application.sass
+++ b/public/stylesheets/sass/application.sass
@@ -652,6 +652,11 @@ form p
   :padding 0
   :margin 0
 
+form p.checkbox_select
+  label
+    :left 20px
+    :top 0
+
 label
   :font
     :family 'Arial', 'Helvetica', sans-serif
@@ -1450,3 +1455,5 @@ ul.aspects
 
   :padding
     :left 120px
+
+
diff --git a/script/websocket_server.rb b/script/websocket_server.rb
index 3b458118b4b9200ef50eb31d79b19dbbcaee8245..cc788e734fdac89ed5dbe76281c23ca9499f9a26 100644
--- a/script/websocket_server.rb
+++ b/script/websocket_server.rb
@@ -48,11 +48,15 @@ begin
                   :debug =>APP_CONFIG[:socket_debug]) do |ws|
       ws.onopen {
 
-        sid = Diaspora::WebSocket.subscribe(ws.request['Path'].gsub('/',''), ws)
+        encoded_cookie = ws.request["Cookie"].gsub("_diaspora_session=","")
+        cookie = Marshal.load(encoded_cookie.unpack("m*").first)
+        user_id = cookie["warden.user.user.key"].last
+
+        sid = Diaspora::WebSocket.subscribe(user_id, ws)
 
         ws.onmessage { |msg| SocketsController.new.incoming(msg) }
 
-        ws.onclose { Diaspora::WebSocket.unsubscribe(ws.request['Path'].gsub('/',''), sid) }
+        ws.onclose { Diaspora::WebSocket.unsubscribe(user_id, sid) }
       }
     end
     PID_FILE = APP_CONFIG[:socket_pidfile]
diff --git a/spec/controllers/albums_controller_spec.rb b/spec/controllers/albums_controller_spec.rb
index 21e75068599e94c281079b19b1b6f3c778ec8ab7..78a4b429062d07f17185f037887205860458f78c 100644
--- a/spec/controllers/albums_controller_spec.rb
+++ b/spec/controllers/albums_controller_spec.rb
@@ -22,6 +22,19 @@ describe AlbumsController do
       params = {"album" => {"name" => "Sunsets","to" => @aspect.id.to_s}}
       post :create, params
     end
+
+    context 'with invalid params' do
+      it 'should render a flash error message when album name is blank' do
+        params = {"album" => {"name" => "", "to" => "all"}}
+        post :create, params
+        flash[:error].should == "Failed to create album."
+      end
+      it 'should redirect back to album page for that given aspect' do
+        params = {"album" => {"name" => "", "to" => "all"}}
+        post :create, params
+        response.should redirect_to albums_path(:aspect => "all")
+      end
+    end
   end
 
   describe "#update" do
@@ -29,7 +42,7 @@ describe AlbumsController do
       put :update, :id => @album.id, :album => { :name => "new_name"}
       @album.reload.name.should eql("new_name")
     end
-    
+
     it "doesn't overwrite random attributes" do
       new_user = make_user
       params = {:name => "Bruisers", :person_id => new_user.person.id}
diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb
index 16b0968a4da21e9646d2a2cd9dd8875878ceae46..c69c0f9d533bab3b7ff7b28dbb6c6cb92ec4267f 100644
--- a/spec/controllers/people_controller_spec.rb
+++ b/spec/controllers/people_controller_spec.rb
@@ -22,14 +22,17 @@ describe PeopleController do
 
   it 'should go to the current_user show page' do
     get :show, :id => user.person.id
+    response.should be_success
   end
 
-  it "doesn't error out on an invalid id" do
+  it "redirects on an invalid id" do
     get :show, :id => 'delicious'
+    response.should redirect_to people_path
   end
 
-  it "doesn't error out on a nonexistent person" do
+  it "redirects on a nonexistent person" do
     get :show, :id => user.id
+    response.should redirect_to people_path
   end
 
   describe '#update' do
@@ -50,5 +53,11 @@ describe PeopleController do
         user.person.profile.image_url.should == image_url
       end
     end
+    it 'does not allow mass assignment' do
+      new_user = make_user
+      put :update, :id => user.person.id, :person => {
+        :owner_id => new_user.id}
+      user.person.reload.owner_id.should_not == new_user.id
+    end
   end
 end
diff --git a/spec/controllers/requests_controller_spec.rb b/spec/controllers/requests_controller_spec.rb
index 636d6e2b98b393c3beeaf5ca5c686ab89bcf4459..4a772c5a332347bd9c94868d98adde7fa11ada46 100644
--- a/spec/controllers/requests_controller_spec.rb
+++ b/spec/controllers/requests_controller_spec.rb
@@ -13,48 +13,54 @@ describe RequestsController do
     @user.aspects.create(:name => "lame-os")
   end
 
-  it "should not error out when requesting to be friends with yourself" do
-    put("create", "request" => {
-      "destination_url" => @user.diaspora_handle,
-      "aspect_id" => @user.aspects[0].id 
-      } 
-    )
-    response.should redirect_to aspects_manage_path 
-  end
-
-  it "should not error out when requesting an invalid identity" do
-    put("create", "request" => {
-      "destination_url" => "not_a_@valid_email",
-      "aspect_id" => @user.aspects[0].id 
-      } 
-    )
-    response.should redirect_to aspects_manage_path
-  end
+  describe '#create' do
+    it "redirects when requesting to be friends with yourself" do
+      put("create", "request" => {
+        "destination_url" => @user.diaspora_handle,
+        "aspect_id" => @user.aspects[0].id 
+        } 
+      )
+      response.should redirect_to aspects_manage_path 
+    end
 
-  it "should not error out when requesting an invalid identity with a port number" do
-    put("create", "request" => {
-      "destination_url" => "johndoe@email.com:3000",
-      "aspect_id" => @user.aspects[0].id 
-      } 
-    )
-    response.should redirect_to aspects_manage_path
-  end
+    it "flashes and redirects when requesting an invalid identity" do
+      put("create", "request" => {
+        "destination_url" => "not_a_@valid_email",
+        "aspect_id" => @user.aspects[0].id 
+        } 
+      )
+      flash[:error].should_not be_blank
+      response.should redirect_to aspects_manage_path
+    end
 
-  it "should not error out when requesting an identity from an invalid server" do
-    stub_request(:get, /notadiasporaserver\.com/).to_raise(Errno::ETIMEDOUT)
-    put("create", "request" => {
-      "destination_url" => "johndoe@notadiasporaserver.com",
-      "aspect_id" => @user.aspects[0].id 
-      } 
-    )
-    response.should redirect_to aspects_manage_path
-  end
+    it "flashes and redirects when requesting an invalid identity with a port number" do
+      put("create", "request" => {
+        "destination_url" => "johndoe@email.com:3000",
+        "aspect_id" => @user.aspects[0].id 
+        } 
+      )
+      flash[:error].should_not be_blank
+      response.should redirect_to aspects_manage_path
+    end
 
-  it 'should redirect to the page which you called it from ' do
-    pending "i need to figure out how to do this"
-  end
+    it "redirects when requesting an identity from an invalid server" do
+      stub_request(:get, /notadiasporaserver\.com/).to_raise(Errno::ETIMEDOUT)
+      put("create", "request" => {
+        "destination_url" => "johndoe@notadiasporaserver.com",
+        "aspect_id" => @user.aspects[0].id 
+        } 
+      )
+      response.should redirect_to aspects_manage_path
+    end
 
-  it 'should not blow up if there is a problem mid way thru the webfinger process' do
-    pending "i need to do this tomorrow"
+    it 'should redirect to the page which you called it from ' do
+      pending "This controller should probably redirect to :back"
+      put("create", "request" => {
+        "destination_url" => "johndoe@notadiasporaserver.com",
+        "aspect_id" => @user.aspects[0].id 
+        } 
+      )
+      response.should redirect_to(:back)
+    end
   end
 end
diff --git a/spec/fixtures/hcard_response b/spec/fixtures/hcard_response
index c3bfb2840ba320185ffe26d6dd26b6d8cffc2de4..d229660d2fed158559463eb173d6bbd3e4de9ce9 100644
--- a/spec/fixtures/hcard_response
+++ b/spec/fixtures/hcard_response
@@ -43,6 +43,12 @@
         <dt>Note</dt> 
         <dd class="note">Diaspora is awesome! vi is better than emacs!</dd> 
       </dl> 
+      <dl class='entity_searchable'> 
+        <dt>Searchable</dt> 
+        <dd> 
+          <span class='searchable'>false</span> 
+        </dd> 
+      </dl>
     </div> 
   </div> 
 </div> 
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 0ba2bb28a14c50e75e9207071f6909c32a414ed0..9e7cb7f4c5b697211f58ab52d6089dbad1532892 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -18,4 +18,155 @@ describe ApplicationHelper do
     person_url(@user).should == "/users/#{@user.id}"
   end
 
+  describe "markdownify" do
+    describe "autolinks" do
+      it "should not allow basic XSS/HTML" do
+        markdownify("<script>alert('XSS is evil')</script>").should == "&lt;script&gt;alert('XSS is evil')&lt;/script&gt;"
+      end
+
+      it "should recognize basic http links (1/3)" do
+        proto="http"
+        url="bugs.joindiaspora.com/issues/332"
+        markdownify(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
+      end
+
+      it "should recognize basic http links (2/3)" do
+        proto="http"
+        url="webmail.example.com?~()!*/"
+        markdownify(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
+      end
+
+      it "should recognize basic http links (3/3)" do
+        proto="http"
+        url="127.0.0.1:3000/users/sign_in"
+        markdownify(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
+      end
+
+      it "should recognize secure https links" do
+        proto="https"
+        url="127.0.0.1:3000/users/sign_in"
+        markdownify(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
+      end
+
+      it "should recognize youtube links" do
+        proto="http"
+        videoid = "0x__dDWdf23"
+        url="www.youtube.com/watch?v="+videoid+"&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
+        title = "UP & down & UP & down &amp;"
+        mock_http = mock("http")
+        Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
+        mock_http.should_receive(:get).with('/feeds/api/videos/'+videoid+'?v=2', nil).and_return([nil, 'Foobar <title>'+title+'</title> hallo welt <asd><dasdd><a>dsd</a>'])
+        res = markdownify(proto+'://'+url)
+        res.should == "<a onclick=\"openVideo('youtube.com', '"+videoid+"', this)\" href=\"#video\">Youtube: "+title+"</a>"
+      end
+
+      it "should recognize a bunch of different links" do
+        message = "http:// Hello World, this is for www.joindiaspora.com and not for http://www.google.com though their Youtube service is neat, take http://www.youtube.com/watch?v=foobar or www.youtube.com/watch?foo=bar&v=BARFOO&whatever=related It is a good idea we finally have youtube, so enjoy this video http://www.youtube.com/watch?v=rickrolld"
+        mock_http = mock("http")
+        Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
+        mock_http.should_receive(:get).with('/feeds/api/videos/foobar?v=2', nil).and_return([nil, 'Foobar <title>F 007 - the bar is not enough</title> hallo welt <asd><dasdd><a>dsd</a>'])
+        mock_http.should_receive(:get).with('/feeds/api/videos/BARFOO?v=2', nil).and_return([nil, 'Foobar <title>BAR is the new FOO</title> hallo welt <asd><dasdd><a>dsd</a>'])
+        mock_http.should_receive(:get).with('/feeds/api/videos/rickrolld?v=2', nil).and_return([nil, 'Foobar <title>Never gonne give you up</title> hallo welt <asd><dasdd><a>dsd</a>'])
+        res = markdownify(message)
+        res.should == "http:// Hello World, this is for <a target=\"_blank\" href=\"http://www.joindiaspora.com\">www.joindiaspora.com</a> and not for <a target=\"_blank\" href=\"http://www.google.com\">www.google.com</a> though their Youtube service is neat, take <a onclick=\"openVideo('youtube.com', 'foobar', this)\" href=\"#video\">Youtube: F 007 - the bar is not enough</a> or <a onclick=\"openVideo('youtube.com', 'BARFOO', this)\" href=\"#video\">Youtube: BAR is the new FOO</a> It is a good idea we finally have youtube, so enjoy this video <a onclick=\"openVideo('youtube.com', 'rickrolld', this)\" href=\"#video\">Youtube: Never gonne give you up</a>"
+      end
+
+      it "should recognize basic ftp links" do
+        proto="ftp"
+        url="ftp.uni-kl.de/CCC/26C3/mp4/26c3-3540-en-a_hackers_utopia.mp4"
+        # I did not watch that one, but the title sounds nice :P
+        markdownify(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
+      end
+
+      it "should recognize www links" do
+        url="www.joindiaspora.com"
+        markdownify(url).should == "<a target=\"_blank\" href=\"http://"+url+"\">"+url+"</a>"
+      end
+    end
+
+    describe "weak emphasis" do
+      it "should be recognized (1/2)" do
+        message = "*some text* some text *some text* some text"
+        markdownify(message).should == "<em>some text</em> some text <em>some text</em> some text"
+      end
+
+      it "should be recognized (2/2)" do
+        message = "_some text_ some text _some text_ some text"
+        markdownify(message).should == "<em>some text</em> some text <em>some text</em> some text"
+      end
+    end
+
+    describe "strong emphasis" do
+      it "should be recognized (1/2)" do
+        message = "**some text** some text **some text** some text"
+        markdownify(message).should == "<strong>some text</strong> some text <strong>some text</strong> some text"
+      end
+
+      it "should be recognized (2/2)" do
+        message = "__some text__ some text __some text__ some text"
+        markdownify(message).should == "<strong>some text</strong> some text <strong>some text</strong> some text"
+      end
+    end
+
+    describe "nested weak and strong emphasis" do
+      it "should be rendered correctly" do
+        message = "__this is _some_ text__"
+        markdownify(message).should == "<strong>this is <em>some</em> text</strong>"
+        message = "*this is **some** text*"
+        markdownify(message).should == "<em>this is <strong>some</strong> text</em>"
+        message = "___some text___"
+        markdownify(message).should == "<em><strong>some text</strong></em>"
+      end
+    end
+
+    describe "links" do
+      it "should be recognized without title attribute" do
+        message = "[link text](http://someurl.com) [link text](http://someurl.com)"
+        markdownify(message).should == '<a target="_blank" href="http://someurl.com">link text</a> <a target="_blank" href="http://someurl.com">link text</a>'
+      end
+
+      it "should be recognized with title attribute" do
+        message = '[link text](http://someurl.com "some title") [link text](http://someurl.com "some title")'
+        markdownify(message).should == '<a target="_blank" href="http://someurl.com" title="some title">link text</a> <a target="_blank" href="http://someurl.com" title="some title">link text</a>'
+      end
+    end
+
+    describe "nested emphasis and links tags" do
+      it "should be rendered correctly" do
+        message = '[**some *link* text**](someurl.com "some title")'
+        markdownify(message).should == '<a target="_blank" href="someurl.com" title="some title"><strong>some <em>link</em> text</strong></a>'
+      end
+    end
+
+    it "should allow escaping" do
+      message = '*some text* \\*some text* \\**some text* _some text_ \\_some text_ \\__some text_'
+      markdownify(message).should == "<em>some text</em> *some text<em> *</em>some text <em>some text</em> _some text<em> _</em>some text"
+    end
+
+    describe "options" do
+      before do
+        @message = "http://url.com www.url.com www.youtube.com/watch?foo=bar&v=BARFOO&whatever=related *emphasis* __emphasis__ [link](www.url.com) [link](url.com \"title\")"
+      end
+
+      it "should allow to render only autolinks" do
+        res = markdownify(@message, :youtube => false, :emphasis => false, :links => false)
+        res.should == "<a target=\"_blank\" href=\"http://url.com\">url.com</a> <a target=\"_blank\" href=\"http://www.url.com\">www.url.com</a> <a target=\"_blank\" href=\"http://www.youtube.com/watch?foo=bar&amp;v=BARFOO&amp;whatever=related\">www.youtube.com/watch?foo=bar&amp;v=BARFOO&amp;whatever=related</a> *emphasis* __emphasis__ [link](www.url.com) [link](url.com &quot;title&quot;)"
+      end
+
+      it "should allow to render only youtube autolinks" do
+        res = markdownify(@message, :autolinks => false, :emphasis => false, :links => false)
+        res.should == "http://url.com www.url.com <a onclick=\"openVideo('youtube.com', 'BARFOO', this)\" href=\"#video\">Youtube: BAR is the new FOO</a> *emphasis* __emphasis__ [link](www.url.com) [link](url.com &quot;title&quot;)"
+      end
+
+      it "should allow to render only emphasis tags" do
+        res = markdownify(@message, :autolinks => false, :youtube => false, :links => false)
+        res.should == "http://url.com www.url.com www.youtube.com/watch?foo=bar&amp;v=BARFOO&amp;whatever=related <em>emphasis</em> <strong>emphasis</strong> [link](www.url.com) [link](url.com &quot;title&quot;)"
+      end
+
+      it "should allo to render only links tags" do
+        res = markdownify(@message, :autolinks => false, :youtube => false, :emphasis => false)
+        res.should == "http://url.com www.url.com www.youtube.com/watch?foo=bar&amp;v=BARFOO&amp;whatever=related *emphasis* __emphasis__ <a target=\"_blank\" href=\"www.url.com\">link</a> <a target=\"_blank\" href=\"url.com\" title=\"title\">link</a>"
+      end
+    end
+  end
 end
diff --git a/spec/helpers/status_messages_helper_spec.rb b/spec/helpers/status_messages_helper_spec.rb
deleted file mode 100644
index 0aee3826ada8d4e01e265ef3db503c55ba460d83..0000000000000000000000000000000000000000
--- a/spec/helpers/status_messages_helper_spec.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-#   Copyright (c) 2010, Diaspora Inc.  This file is
-#   licensed under the Affero General Public License version 3 or later.  See
-#   the COPYRIGHT file.
-
-require 'spec_helper'
-
-describe StatusMessagesHelper do
-  it "should not allow basic XSS/HTML" do
-    make_links("<script>alert('XSS is evil')</script>").should == "&lt;script&gt;alert('XSS is evil')&lt;/script&gt;"
-  end
-
-  it "should recognize basic http links (1/3)" do
-    proto="http"
-    url="bugs.joindiaspora.com/issues/332"
-    make_links(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
-  end
-
-  it "should recognize basic http links (2/3)" do
-    proto="http"
-    url="webmail.example.com?~()!*/"
-    make_links(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
-  end
-
-  it "should recognize basic http links (3/3)" do
-    proto="http"
-    url="127.0.0.1:3000/users/sign_in"
-    make_links(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
-  end
-
-  it "should recognize secure https links" do
-    proto="https"
-    url="127.0.0.1:3000/users/sign_in"
-    make_links(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
-  end
-
-  it "should recognize youtube links" do
-    proto="http"
-    videoid = "0x__dDWdf23"
-    url="www.youtube.com/watch?v="+videoid+"&a=GxdCwVVULXdvEBKmx_f5ywvZ0zZHHHDU&list=ML&playnext=1"
-    title = "UP & down & UP & down &amp;"
-    mock_http = mock("http")
-    Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
-    mock_http.should_receive(:get).with('/feeds/api/videos/'+videoid+'?v=2', nil).and_return([nil, 'Foobar <title>'+title+'</title> hallo welt <asd><dasdd><a>dsd</a>'])
-    res = make_links(proto+'://'+url)
-    res.should == "<a onclick=\"openVideo('youtube.com', '"+videoid+"', this)\" href=\"#video\">Youtube: "+title+"</a>"
-  end
-
-  it "should recognize a bunch of different links" do
-    message = "http:// Hello World, this is for www.joindiaspora.com and not for http://www.google.com though their Youtube service is neat, take http://www.youtube.com/watch?v=foobar or www.youtube.com/watch?foo=bar&v=BARFOO&whatever=related It is a good idea we finally have youtube, so enjoy this video http://www.youtube.com/watch?v=rickrolld"
-    mock_http = mock("http")
-    Net::HTTP.stub!(:new).with('gdata.youtube.com', 80).and_return(mock_http)
-    mock_http.should_receive(:get).with('/feeds/api/videos/foobar?v=2', nil).and_return([nil, 'Foobar <title>F 007 - the bar is not enough</title> hallo welt <asd><dasdd><a>dsd</a>'])
-    mock_http.should_receive(:get).with('/feeds/api/videos/BARFOO?v=2', nil).and_return([nil, 'Foobar <title>BAR is the new FOO</title> hallo welt <asd><dasdd><a>dsd</a>'])
-    mock_http.should_receive(:get).with('/feeds/api/videos/rickrolld?v=2', nil).and_return([nil, 'Foobar <title>Never gonne give you up</title> hallo welt <asd><dasdd><a>dsd</a>'])
-    res = make_links(message)
-    res.should == "http:// Hello World, this is for <a target=\"_blank\" href=\"http://www.joindiaspora.com\">www.joindiaspora.com</a> and not for <a target=\"_blank\" href=\"http://www.google.com\">www.google.com</a> though their Youtube service is neat, take <a onclick=\"openVideo('youtube.com', 'foobar', this)\" href=\"#video\">Youtube: F 007 - the bar is not enough</a> or <a onclick=\"openVideo('youtube.com', 'BARFOO', this)\" href=\"#video\">Youtube: BAR is the new FOO</a> It is a good idea we finally have youtube, so enjoy this video <a onclick=\"openVideo('youtube.com', 'rickrolld', this)\" href=\"#video\">Youtube: Never gonne give you up</a>"
-  end
-
-  it "should recognize basic ftp links" do
-    proto="ftp"
-    url="ftp.uni-kl.de/CCC/26C3/mp4/26c3-3540-en-a_hackers_utopia.mp4"
-    # I did not watch that one, but the title sounds nice :P
-    make_links(proto+"://"+url).should == "<a target=\"_blank\" href=\""+proto+"://"+url+"\">"+url+"</a>"
-  end
-
-  it "should recognize www links" do
-    url="www.joindiaspora.com"
-    make_links(url).should == "<a target=\"_blank\" href=\"http://"+url+"\">"+url+"</a>"
-  end
-
-  
-end
diff --git a/spec/javascripts/aspect-edit-spec.js b/spec/javascripts/aspect-edit-spec.js
index 5405f480e3dbc521a9a4b83b1e60e8b72ce18aae..9c2da462166a9558158b92643e8d999b86fd6e1b 100644
--- a/spec/javascripts/aspect-edit-spec.js
+++ b/spec/javascripts/aspect-edit-spec.js
@@ -1,27 +1,30 @@
-describe("editing aspects", function() {
+describe("AspectEdit", function() {
+
+//  describe("initialize", function() {
+//
+//  });
 
   describe("decrementRequestsCounter", function() {
     describe("when there is one request", function() {
       it("removes the counter from the new requests div", function() {
         $('#jasmine_content').html("<div class='new_requests'>Requests (1)</div>");
-        decrementRequestsCounter();
+        AspectEdit.decrementRequestsCounter();
         expect($('.new_requests').first().html()).toEqual("Requests");
       });
     });
     describe("when there is more than one request", function() {
       it("decrements the request counter", function() {
         $('#jasmine_content').html("<div class='new_requests'>Requests (67)</div>");
-        decrementRequestsCounter();
+        AspectEdit.decrementRequestsCounter();
         expect($('.new_requests').first().html()).toEqual("Requests (66)");
       });
     });
     describe("error cases", function() {
       it("fails silently if there are no requests", function() {
         $('#jasmine_content').html("<div class='new_requests'>Requests</div>");
-        decrementRequestsCounter();
+        AspectEdit.decrementRequestsCounter();
         expect($('.new_requests').first().html()).toEqual("Requests");
       });
     });
   });
-
 });
\ No newline at end of file
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index 74645d1e6ddc2a48348f5fe8d0628c75daee584d..dda4a5fdb8dcc362b6f8f4117103e8435fa172dc 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -12,6 +12,7 @@
 #
 src_files:
   - public/javascripts/jquery142.js
+  - public/javascripts/jquery-ui-1.8.4.custom.min.js
   - public/javascripts/aspect-edit.js
 
 # stylesheets
diff --git a/spec/lib/diaspora/importer_spec.rb b/spec/lib/diaspora/importer_spec.rb
deleted file mode 100644
index f855f8bd0037fd31fdf61e3262fc9d3dde6bebc2..0000000000000000000000000000000000000000
--- a/spec/lib/diaspora/importer_spec.rb
+++ /dev/null
@@ -1,254 +0,0 @@
-#   Copyright (c) 2010, Diaspora Inc.  This file is
-#   licensed under the Affero General Public License version 3 or later.  See
-#   the COPYRIGHT file.
-
-require 'spec_helper'
-require File.join(Rails.root, 'lib/diaspora/exporter')
-require File.join(Rails.root, 'lib/diaspora/importer')
-
-describe Diaspora::Importer do
-  def setup_for_exporting
-    # Five users on pod
-    @user1 = make_user
-    @user2 = make_user
-    @user3 = make_user
-    @user4 = make_user
-    @user5 = make_user
-
-    # Two external people referenced on pod
-    @person1 = Factory(:person)
-    @person2 = Factory(:person)
-
-    # User1 has four aspects(1-4), each following user has one aspect
-    @aspect1 = @user1.aspects.create(:name => "Dudes") 
-    @aspect2 = @user1.aspects.create(:name => "Girls")
-    @aspect3 = @user1.aspects.create(:name => "Bros")
-    @aspect4 = @user1.aspects.create(:name => "People")
-    @aspect5 = @user2.aspects.create(:name => "Abe Lincolns")
-    @aspect6 = @user3.aspects.create(:name => "Cats")
-    @aspect7 = @user4.aspects.create(:name => "Dogs")
-    @aspect8 = @user5.aspects.create(:name => "Hamsters")
-    @aspect9 = @user5.aspects.create(:name => "Gophers")
-
-    @aspect10 = @user1.aspects.create(:name => "Work") 
-    @aspect11 = @user1.aspects.create(:name => "Family")
-
-    # User1 posts one status messages to aspects (1-4), two other users post message to one aspect
-    @status_message1 = @user1.post(:status_message, :message => "One", :public => false, :to => @aspect1.id)
-    @status_message2 = @user1.post(:status_message, :message => "Two", :public => false, :to => @aspect2.id)
-    @status_message3 = @user1.post(:status_message, :message => "Three", :public => false, :to => @aspect3.id)
-    @status_message4 = @user1.post(:status_message, :message => "Four", :public => false, :to => @aspect4.id)
-    @status_message5 = @user2.post(:status_message, :message => "Five", :public => false, :to => @aspect5.id)
-    @status_message6 = @user3.post(:status_message, :message => "Six", :public => false, :to => @aspect6.id)
-    @status_message7 = @user5.post(:status_message, :message => "Seven", :public => false, :to => @aspect9.id)
-
-    @aspect1.posts << @status_message1
-    @aspect2.posts << @status_message2
-    @aspect3.posts << @status_message3
-    @aspect4.posts << @status_message4
-
-    # Friend users with user1
-    friend_users( @user1, @aspect1, @user2, @aspect5 )
-    friend_users( @user1, @aspect2, @user3, @aspect6 )
-    friend_users( @user1, @aspect3, @user4, @aspect7 )
-    friend_users( @user1, @aspect4, @user5, @aspect8 )
-
-    # Friend users 4 and 5
-    friend_users( @user5, @aspect9, @user4, @aspect7 )
-
-    # Generate status messages and receive for user1
-    @user2.receive @status_message1.to_diaspora_xml, @user1.person
-    @user3.receive @status_message2.to_diaspora_xml, @user1.person
-    @user4.receive @status_message3.to_diaspora_xml, @user1.person
-    @user5.receive @status_message4.to_diaspora_xml, @user1.person
-    @user1.receive @status_message5.to_diaspora_xml, @user2.person
-    @user1.receive @status_message6.to_diaspora_xml, @user3.person
-
-    # Generate status message and recieve between user4 and user5
-    @user4.receive @status_message7.to_diaspora_xml, @user5.person
-
-
-  end
-
-  before(:all) do
-    DatabaseCleaner.clean
-    UserFixer.load_user_fixtures
-    setup_for_exporting
-    # Generate exported XML for user1
-    exporter = Diaspora::Exporter.new(Diaspora::Exporters::XML)
-    @user1.aspects.reload
-    @xml = exporter.execute(@user1)
-
-    @old_user = @user1
-
-    # Remove user1 from the server
-    @user1.aspects.each( &:delete )
-    @user1.raw_visible_posts.find_all_by_person_id(@user1.person.id).each( &:delete )
-    @user1.delete
-  end
-
-  it 'should gut check this test' do 
-    setup_for_exporting
-    @user1.friends.count.should be 4
-
-    @user1.contact_for(@user2.person).should_not be_nil
-    @user1.contact_for(@user3.person).should_not be_nil
-    @user1.contact_for(@user4.person).should_not be_nil
-    @user1.contact_for(@user5.person).should_not be_nil
-    
-    # User is generated with two pre-populated aspects
-    @user1.aspects.count.should be 6
-    @user1.aspects.find_by_name("Dudes").people.find_by_person_id(@user2.person.id).should_not be_nil
-    @user1.aspects.find_by_name("Dudes").posts.should include @status_message5
-    
-    @user1.raw_visible_posts.count.should be 6
-    @user1.raw_visible_posts.find_all_by_person_id(@user1.person.id).count.should be 4
-    @user1.raw_visible_posts.find_all_by_person_id(@user1.person.id).should_not include @status_message7
-  end
-
-  context 'parsing a user' do
-
-    before(:each) do
-      @importer = Diaspora::Importer.new(Diaspora::Parsers::XML)
-      @doc = Nokogiri::XML::parse(@xml)
-    end
-
-    describe '#parse_user_and_person' do
-      before(:each) do
-        @user, @person = @importer.parse_user_and_person(@doc)
-      end
-
-      it 'should set username' do
-        @user.username.should == @old_user.username
-      end
-
-      it 'should set private key' do
-        @user.serialized_private_key.should_not be nil
-        @user.serialized_private_key.should == @old_user.serialized_private_key
-      end
-
-    end
-    
-    describe '#parse_aspects' do
-      let(:aspects) { @importer.parse_aspects(@doc) }
-
-      it 'should return valid aspects' do 
-        aspects.all?(&:valid?).should be true
-      end
-
-      it 'should return an array' do
-        aspects.count.should == 6
-      end
-
-      it 'should should have post ids' do
-        aspects.any?{|x| x.post_ids.count > 0}.should be true
-      end
-    end
-
-    describe '#parse_contacts' do
-      let(:contacts) { @importer.parse_contacts(@doc) }
-
-      it 'should return an array' do
-        contacts.count.should == 4
-      end
-
-      it 'should should have post ids' do
-        contacts.all?{|x| x.aspect_names.count > 0}.should be true
-      end
-      
-      it 'should should have a person id' do
-        contacts.all?{|x| x.person_id.nil? ||  x.person_id == ""}.should be false
-      end
-    end
-
-    describe '#parse_people' do
-      let(:people) { @importer.parse_people(@doc) }
-
-      it 'should return an array' do
-        people.count.should == 4 
-      end
-    end
-
-    describe '#parse_posts' do
-      let(:posts) { @importer.parse_posts(@doc) }
-
-      it 'should return an array' do
-        posts.count.should == 4
-      end
-
-      it 'should return vaild posts' do         
-        posts.all?(&:valid?).should be true
-      end
-    end
-
-  end
-
-  describe 'importing a user' do
-
-    context '#execute' do
-      before(:each) do
-        # Generate exported XML for user1
-        exporter = Diaspora::Exporter.new(Diaspora::Exporters::XML)
-        @xml = exporter.execute(@user1)
-        @username =@user1.username
-        # Remove user1 from the server
-        @user1.aspects.each( &:delete )
-        @user1.friends.each( &:delete )
-        @user1.raw_visible_posts.find_all_by_person_id(@user1.person.id).each( &:delete )
-        @user1.delete
-
-        @importer = Diaspora::Importer.new(Diaspora::Parsers::XML)
-      end
-
-      it 'should import' do
-        pending "there is some weirdness with diaspora handle we need to look into... and this test needs love
-        the test passes when the validations are set to false when saving the user in the importer"
-        
-        User.delete_all
-        Person.delete_all
-        Post.delete_all
-        StatusMessage.delete_all
-        Aspect.delete_all
-        Contact.delete_all
-
-        User.count.should == 0
-        Person.count.should == 0
-        
-        @importer.execute(@xml,
-                          :email => "bob@bob.com",
-                          :password => "bobbybob",
-                          :password => "bobbybob",
-                          :diaspora_handle => "#{@username}@#{APP_CONFIG[:terse_pod_url]}")
-        
-        User.count.should == 1
-        n = User.first
-        Post.count.should == 4 
-        n.aspects.count.should  == 6
-        Person.count.should be == 5 
-        Contact.count.should be == 4 
-
-        # need to check this 
-        #User.first.person.diaspora_handle.should == User.first.diaspora_handle
-        User.first.diaspora_handle.should == "#{@username}@#{APP_CONFIG[:terse_pod_url]}"
-     
-
-        Person.find_by_id( @user1.person.id ).nil?.should == false
-        Person.find_by_id( @user2.person.id ).nil?.should == false
-
-        n.aspects.count.should == 6
- 
-        people_count = 0
-        n.aspects.each{|x| people_count += x.people.count }
-        people_count.should == 4
-
-        post_count = 0
-        n.aspects.reload
-        n.aspects.each{ |x| post_count += x.post_ids.count }
-        post_count.should == 4
-        
-        n.friends.count.should be 4
-      end
-    end
-  end
-end
-
diff --git a/spec/lib/hcard_spec.rb b/spec/lib/hcard_spec.rb
index 8c75466f5ee29f58f966fc915e808cdef6a84968..fbd4bb42c50c536ed10d667792ada64281148edb 100644
--- a/spec/lib/hcard_spec.rb
+++ b/spec/lib/hcard_spec.rb
@@ -6,13 +6,13 @@ require 'spec_helper'
 require File.join(Rails.root, 'lib/hcard')
 
 describe HCard do
-  it 'should retreive and parse an hcard' do
-    stub_success("tom@tom.joindiaspora.com")
-    f = Redfinger.finger('tom@tom.joindiaspora.com')
-    hcard = HCard.find f.hcard.first[:href]
+  it 'should parse an hcard' do
+    raw_hcard = hcard_response 
+    hcard = HCard.build raw_hcard
     hcard[:family_name].include?("Hamiltom").should be true
     hcard[:given_name].include?("Alex").should be true
     hcard[:photo].include?("tom.jpg").should be true
-    hcard[:url].should  == "http://tom.joindiaspora.com/"
+    hcard[:url].should == "http://tom.joindiaspora.com/"
+    hcard[:searchable].should == "false"
   end
 end
diff --git a/spec/lib/verify_spec.rb b/spec/lib/verify_spec.rb
deleted file mode 100644
index 9dca1cb783e1eb6ea383500e2f0c8d8424ce0078..0000000000000000000000000000000000000000
--- a/spec/lib/verify_spec.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-#   Copyright (c) 2010, Diaspora Inc.  This file is
-#   licensed under the Affero General Public License version 3 or later.  See
-#   the COPYRIGHT file.
-
-require 'spec_helper'
-require File.join(Rails.root, 'lib/diaspora/importer')
-
-describe Diaspora::Importer do
-
-  let!(:user1) { make_user }
-  let!(:user2) { make_user }
-  let!(:user3) { make_user }
-
-  let(:aspect1) { user1.aspects.create(:name => "Work")   }
-  let(:aspect2) { user2.aspects.create(:name => "Family") }
-  let(:aspect3) { user3.aspects.create(:name => "Pivots") }
-
-  let!(:status_message1) { user1.post(:status_message, :message => "One", :public => true, :to => aspect1.id) }
-  let!(:status_message2) { user1.post(:status_message, :message => "Two", :public => true, :to => aspect1.id) }
-  let!(:status_message3) { user2.post(:status_message, :message => "Three", :public => false, :to => aspect2.id) }
-
-  let(:importer) { Diaspora::Importer.new(Diaspora::Parsers::XML) }
-
-  context 'serialized user' do
-    describe '#verify_user' do
-      it 'should return true for a new valid user' do
-        new_user = make_user
-        new_user.delete
-        importer.verify_user(new_user).should be true
-      end
-
-      it 'should return false if vaild user already exists' do
-        u = User.first
-        lambda{ importer.verify_user(user1) }.should raise_error
-      end
-    end
-
-    describe '#verify_person_for_user' do
-      it 'should pass if keys match' do
-        importer.verify_person_for_user(user1, user1.person).should be true
-      end
-
-      it 'should fail if private and public keys do not match' do
-        person = Factory(:person)
-        lambda{ importer.verify_person_for_user(user1, person) }.should raise_error
-      end
-
-      it 'should pass if the person does not exist' do 
-        user = Factory.build(:user)
-        importer.verify_person_for_user(user, user.person)
-      end
-    end
-
-    describe 'verify contacts' do
-      let(:contact1)     {Contact.new(:user => user1, :person => user2.person, :aspects => [aspect1])}
-      let(:contact2)     {Contact.new(:user => user1, :person => user3.person, :aspects => [aspect2])}
-      let(:contact3)     {Contact.new(:user => user1, :person => user3.person, :aspects => [aspect3])}
-      let(:less_contacts) {[contact1]}
-      let(:same_contacts) {[contact1, contact2]}
-      let(:more_contacts) {[contact1, contact2, contact3]}
-
-      let(:person_ids)    {[user2.person.id, user3.person.id]}
-
-
-      it 'should be false if the number of the number of contacts is not equal to the number of imported people' do
-        importer.verify_contacts(less_contacts, person_ids).should be false
-        importer.verify_contacts(same_contacts, person_ids).should be true
-        importer.verify_contacts(more_contacts, person_ids).should be false
-      end
-    end
-
-    describe '#filter_posts' do
-      it 'should make sure all found posts are owned by the user' do
-        posts = [status_message1, status_message2]
-        whitelist = importer.filter_posts(posts, user1.person)[:whitelist]
-
-        whitelist.should have(2).posts
-        whitelist.should include status_message1.id.to_s
-        whitelist.should include status_message2.id.to_s
-      end
-
-      it 'should remove posts not owned by the user' do
-        posts = [status_message1, status_message2, status_message3]
-        whitelist = importer.filter_posts(posts, user1.person)[:whitelist]
-
-        whitelist.should have(2).posts
-        whitelist.should_not include status_message3.id
-      end
-
-      it 'should return a list of unknown posts' do
-        posts = [status_message1, status_message2, Factory.build(:status_message)]
-        unknown = importer.filter_posts(posts, user1.person)[:unknown]
-
-        unknown.should have(1).post
-      end
-
-      it 'should generate a whitelist, unknown posts inclusive' do
-        posts = [status_message1, status_message2, Factory.build(:status_message)]
-        filters = importer.filter_posts(posts, user1.person)
-
-        filters[:whitelist].should include filters[:unknown].keys.first
-      end
-    end
-
-    describe '#clean_aspects' do 
-      it 'should purge posts not in whitelist that are present in aspects' do
-        whitelist = {status_message1.id.to_s => true, status_message2.id.to_s => true}
-
-        aspect1.reload
-        aspect1.post_ids << status_message3.id.to_s
-
-        proc{ importer.clean_aspects([aspect1], whitelist) }.should change(aspect1.post_ids, :count).by(-1)
-        aspect1.post_ids.should_not include status_message3.id 
-      end
-    end
-
-    describe '#filter_people' do
-      it 'should filter people who already exist in the database' do
-        new_peep = Factory.build(:person)
-        people = [user1.person, user2.person, new_peep]
-        
-        importer.filter_people(people).keys.should == [new_peep.id.to_s]
-      end
-    end
-  end
-end
diff --git a/spec/models/album_spec.rb b/spec/models/album_spec.rb
index d8226c2dcc4e7da5366e0f475193bdf9937267bf..540d498298df7840a9a0905e51648c207154de43 100644
--- a/spec/models/album_spec.rb
+++ b/spec/models/album_spec.rb
@@ -23,6 +23,15 @@ describe Album do
     album.associations[:photos].type.should == :many
   end
 
+  it 'should be mutable' do
+    post = user.post :album, :name => "hello", :to => aspect.id
+    post.mutable?.should == true   
+  end
+
+  it 'has a diaspora_handle' do
+    album.diaspora_handle.should == user.diaspora_handle
+  end
+
   context 'when an album has two attached images' do
     before do
       2.times do
@@ -65,4 +74,10 @@ describe Album do
     end
   end
 
+  describe 'serialization' do
+    it 'has a diaspora_handle' do
+      album.to_diaspora_xml.include?(user.diaspora_handle).should be_true
+    end
+  end
+
 end
diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb
index 498588fa85e8350d0ec031b5b8aed7a6a9d57841..a7ba0ca0d79ec1ac6b8bd968a05302e89c4b9eac 100644
--- a/spec/models/person_spec.rb
+++ b/spec/models/person_spec.rb
@@ -47,14 +47,15 @@ describe Person do
         @person.diaspora_handle.include?(APP_CONFIG[:terse_pod_url]).should be false
       end
     end
+
     describe 'validation' do
       it 'is unique' do
-        person_two = Factory.build(:person, :url => @person.diaspora_handle)
+        person_two = Factory.build(:person, :diaspora_handle => @person.diaspora_handle)
         person_two.valid?.should be_false
       end
 
       it 'is case insensitive' do
-        person_two = Factory.build(:person, :url => @person.diaspora_handle.upcase)
+        person_two = Factory.build(:person, :url => @person.url.upcase)
         person_two.valid?.should be_false
       end
     end
@@ -187,6 +188,16 @@ describe Person do
       people = Person.search("Casey Grippi")
       people.should == [@friend_four]
     end
+
+    it 'should only display searchable people' do
+      invisible_person = Factory(:person, :profile => {:searchable => false, :first_name => "johnson"})
+      Person.search("johnson").should_not include invisible_person
+      Person.search("").should_not include invisible_person
+    end
+
+    it 'should search on handles' do
+      Person.search(@friend_one.diaspora_handle).should include @friend_one
+    end
   end
 
   context 'people finders for webfinger' do
diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb
index f5d07fc552cce233acdbfc7a16e4ac593c526e23..f0e38fa4210cf4737000f6ecadcc065e01bc2040 100644
--- a/spec/models/photo_spec.rb
+++ b/spec/models/photo_spec.rb
@@ -16,6 +16,9 @@ describe Photo do
 
     @photo = Photo.new(:album => @album)
     @photo.person = @user.person
+    @photo.diaspora_handle = @user.person.diaspora_handle
+
+    @photo2 = @user.post(:photo, :user_file=> File.open(@fixture_name), :to => @aspect.id)
   end
 
   describe "protected attributes" do
@@ -31,6 +34,16 @@ describe Photo do
     end
   end
 
+  it 'should be mutable' do
+    @photo.mutable?.should == true   
+  end
+
+  describe '.instantiate' do
+    it 'sets the persons diaspora handle' do
+      @photo2.diaspora_handle.should == @user.person.diaspora_handle
+    end
+  end
+
   it 'has a constructor' do
     image = File.open(@fixture_name)
     photo = Photo.instantiate(
@@ -88,25 +101,23 @@ describe Photo do
 
   end
 
-  describe 'remote photos' do
-    it 'should write the url on serialization' do
-      @photo.image = File.open(@fixture_name)
-      @photo.image.store!
-      @photo.save
-
-      xml = @photo.to_xml.to_s
-
-      xml.include?(@photo.image.url).should be true
-    end
-
-    it 'should have an album id on serialization' do
+  describe 'serialization' do
+    before do
       @photo.image.store! File.open(@fixture_name)
-      xml = @photo.to_xml.to_s
-      xml.include?(@photo.album_id.to_s).should be true
+      @xml = @photo.to_xml.to_s
     end
-
+    it 'serializes the url' do
+      @xml.include?(@photo.image.url).should be true
+    end
+    it 'serializes the album_id' do
+      @xml.include?(@photo.album_id.to_s).should be true
+    end
+    it 'serializes the diaspora_handle' do
+      @xml.include?(@user.diaspora_handle).should be true
+    end
+  end
+  describe 'remote photos' do
     it 'should set the remote_photo on marshalling' do
-      pending "did the socket get unstubbed?"
       @photo.image.store! File.open(@fixture_name)
 
 
@@ -114,10 +125,6 @@ describe Photo do
       user2 = Factory.create(:user)
       aspect2 = user2.aspects.create(:name => "foobars")
       friend_users(@user, @aspect, user2, aspect2)
-      @photo.person = user2.person
-
-      @photo.save
-      #@photo.reload
 
       url = @photo.url
       thumb_url = @photo.url :thumb_medium
@@ -126,7 +133,7 @@ describe Photo do
       id = @photo.id
 
       @photo.destroy
-      @user.receive xml, @photo.person
+      user2.receive xml, @user.person
 
       new_photo = Photo.first(:id => id)
       new_photo.url.nil?.should be false
diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb
index 587751b0ca036e003932792ea0dfe87d2652dd90..e4ca64938ca90093ecbd2a3537fe4a0edda10f45 100644
--- a/spec/models/post_spec.rb
+++ b/spec/models/post_spec.rb
@@ -29,5 +29,12 @@ describe Post do
       xml.include?(@user.person.diaspora_handle).should be true
     end
   end
+
+  describe '#mutable?' do
+    it 'should be false by default' do
+      post = @user.post :status_message, :message => "hello", :to => @aspect.id
+      post.mutable?.should == false   
+    end
+  end
 end
 
diff --git a/spec/models/user/attack_vectors_spec.rb b/spec/models/user/attack_vectors_spec.rb
index 8ee200dcee296842c4ff67d136809d46da6c541f..9f9b74f6bd50a05f6d3071f8703bc932735365c2 100644
--- a/spec/models/user/attack_vectors_spec.rb
+++ b/spec/models/user/attack_vectors_spec.rb
@@ -17,11 +17,6 @@ describe "attack vectors" do
   let(:user3) { make_user }
   let(:aspect3) { user3.aspects.create(:name => 'heroes') }
 
-  before do
-    friend_users(user, aspect, user2, aspect2)
-    friend_users(user, aspect, user3, aspect3)
-  end
-
   context 'non-friend valid user' do
     
     it 'raises if receives post by non-friend' do
@@ -41,7 +36,23 @@ describe "attack vectors" do
 
   end
 
+  it 'does not let a user attach to posts previously in the db unless its received from the author' do
+    friend_users(user, aspect, user3, aspect3)
+
+    original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
+
+    original_message.diaspora_handle = user.diaspora_handle
+    user3.receive_salmon(user.salmon(original_message).xml_for(user3.person))
+    user3.reload.visible_posts.should_not include(original_message)
+  end
+
   context 'malicious friend attack vector' do
+    before do
+      friend_users(user, aspect, user2, aspect2)
+      friend_users(user, aspect, user3, aspect3)
+    end
+
+
     it 'overwrites messages with a different user' do 
       original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
 
@@ -135,5 +146,18 @@ describe "attack vectors" do
     
       user.reload.friends.count.should == 2
     end
+
+    it 'does not let me update other persons post' do
+      original_message = user2.post :album, :name => 'store this!', :to => aspect2.id
+      user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
+
+      original_message.diaspora_handle = user3.diaspora_handle
+      original_message.name = "bad bad bad"
+      xml = user3.salmon(original_message).xml_for(user.person)
+      user.receive_salmon(xml)
+
+      original_message.reload.name.should == "store this!"
+
+    end
   end
 end
diff --git a/spec/models/user/receive_spec.rb b/spec/models/user/receive_spec.rb
index 7d504f1d32fc8c966c6494981575e86687122fb6..e17b182b0fb716dd7ab7cc1aa22e0fe21d2e42f7 100644
--- a/spec/models/user/receive_spec.rb
+++ b/spec/models/user/receive_spec.rb
@@ -14,11 +14,21 @@ describe User do
 
   let(:user3) { make_user }
   let(:aspect3) { user3.aspects.create(:name => 'heroes') }
+  let(:status) {user.post(:status_message, :message => "Original", :to => aspect.id)}
+  let(:album)  {user.post(:album, :name => "Original", :to => aspect.id)}
 
   before do
     friend_users(user, aspect, user2, aspect2)
   end
 
+  it 'should stream only one message to the everyone aspect when a multi-aspected friend posts' do
+    user.add_person_to_aspect(user2.person.id, user.aspects.create(:name => "villains").id)
+    status = user2.post(:status_message, :message => "Users do things", :to => aspect2.id)
+    xml = status.to_diaspora_xml
+    Diaspora::WebSocket.should_receive(:queue_to_user).exactly(:once)
+    user.receive xml, user2.person
+  end
+
   it 'should be able to parse and store a status message from xml' do
     status_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
 
@@ -41,6 +51,42 @@ describe User do
     user.aspects.size.should == num_aspects
   end
 
+  describe '#receive_salmon' do
+   it 'should handle the case where the webfinger fails' do
+    Person.should_receive(:by_account_identifier).and_return("not a person")
+
+    proc{user2.receive_salmon(user.salmon(status).xml_for(user2.person))}.should_not raise_error
+   end
+  end
+
+  context 'update posts' do
+
+    it 'does not update posts not marked as mutable' do
+      user2.receive_salmon(user.salmon(status).xml_for(user2.person))
+      status.message = 'foo'
+      xml = user.salmon(status).xml_for(user2.person)
+
+      status.reload.message.should == 'Original'
+
+      user2.receive_salmon(xml)
+
+      status.reload.message.should == 'Original'
+    end
+
+    it 'updates posts marked as mutable' do
+      user2.receive_salmon(user.salmon(album).xml_for(user2.person))
+      album.name = 'foo'
+      xml = user.salmon(album).xml_for(user2.person)
+
+      album.reload.name.should == 'Original'
+
+      user2.receive_salmon(xml)
+
+      album.reload.name.should == 'foo'
+    end
+
+  end
+
   describe 'post refs' do
     before do
       @status_message = user2.post :status_message, :message => "hi", :to =>aspect2.id
@@ -113,11 +159,11 @@ describe User do
       post_in_db.comments.should == []
       user2.receive_salmon(@xml)
       post_in_db.reload
-      
+
       post_in_db.comments.include?(@comment).should be true
       post_in_db.comments.first.person.should == local_person
     end
-    
+
     it 'should correctly marshal a stranger for the downstream user' do
       remote_person = user3.person
       remote_person.delete
@@ -127,13 +173,13 @@ describe User do
       Person.should_receive(:by_account_identifier).twice.and_return{ |handle| if handle == user.person.diaspora_handle; user.person.save
         user.person; else; remote_person.save; remote_person; end }
 
-      
+
       user2.reload.raw_visible_posts.size.should == 1
       post_in_db = user2.raw_visible_posts.first
       post_in_db.comments.should == []
       user2.receive_salmon(@xml)
       post_in_db.reload
-      
+
       post_in_db.comments.include?(@comment).should be true
       post_in_db.comments.first.person.should == remote_person
     end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 0772246748f5b37753a9e63cebfb9abebd89a68d..55c5575fb2816bf708d48b7e3e5d3519033aa111 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -22,7 +22,6 @@ describe User do
       new_user.id.should_not == user.id
     end
     it 'does not overwrite old users with create' do
-      pending "Why do you want to set ids directly? MONGOMAPPERRRRR!!!"
           params = {:username => "ohai",
                     :email => "ohai@example.com",
                     :password => "password",
@@ -163,13 +162,16 @@ describe User do
         }
         @user = User.build(params)
       end
-      it "makes a valid user" do
-        @user.should be_valid
+      it "does not save" do
         @user.persisted?.should be_false
+        @user.person.persisted?.should be_false
         User.find_by_username("ohai").should be_nil
       end
       it 'saves successfully' do
+        @user.should be_valid
         @user.save.should be_true
+        @user.persisted?.should be_true
+        @user.person.persisted?.should be_true
         User.find_by_username("ohai").should == @user
       end
     end