diff --git a/troggle/context.py b/troggle/context.py
new file mode 100644
index 000000000..f0fd20857
--- /dev/null
+++ b/troggle/context.py
@@ -0,0 +1,4 @@
+import troggle.settings as settings
+
+def settingsContext(request):
+    return { 'settings':settings }
\ No newline at end of file
diff --git a/troggle/expo/admin.py b/troggle/expo/admin.py
index 52138af30..d5a7ddd6c 100644
--- a/troggle/expo/admin.py
+++ b/troggle/expo/admin.py
@@ -18,8 +18,13 @@ class SurveyAdmin(admin.ModelAdmin):
 class LogbookEntryAdmin(admin.ModelAdmin):
     search_fields = ('title','expedition__year')
 
+class PersonExpeditionInline(admin.TabularInline):
+    model = PersonExpedition
+    extra = 1
+
 class PersonAdmin(admin.ModelAdmin):
     search_fields = ('first_name','last_name')
+    inlines = (PersonExpeditionInline,)
     
 class PersonExpeditionAdmin(admin.ModelAdmin):
     search_fields = ('person__first_name','expedition__year')
diff --git a/troggle/expo/forms.py b/troggle/expo/forms.py
index c8e284268..91f39f094 100644
--- a/troggle/expo/forms.py
+++ b/troggle/expo/forms.py
@@ -1,6 +1,10 @@
 from django.forms import ModelForm
-from models import Cave
+from models import Cave, Person
 
 class CaveForm(ModelForm):
     class Meta:
-        model = Cave
\ No newline at end of file
+        model = Cave
+
+class PersonForm(ModelForm):
+    class Meta:
+        model = Person
\ No newline at end of file
diff --git a/troggle/expo/models.py b/troggle/expo/models.py
index 2b3919c91..98b5d2b5d 100644
--- a/troggle/expo/models.py
+++ b/troggle/expo/models.py
@@ -4,6 +4,7 @@ from django.forms import ModelForm
 from django.db import models
 from django.contrib import admin
 from django.core.files.storage import FileSystemStorage
+from django.contrib.auth.models import User
 import os
 import troggle.settings as settings
 import datetime
@@ -59,6 +60,7 @@ class Person(models.Model):
     mug_shot    = models.CharField(max_length=100, blank=True,null=True)
     blurb = models.TextField(blank=True,null=True)
     href        = models.CharField(max_length=200)
+    user	= models.ForeignKey(User, unique=True, null=True, blank=True)
     
     class Meta:
 	    verbose_name_plural = "People"
@@ -482,4 +484,4 @@ class Survey(models.Model):
     def elevations(self):
 	    return self.scannedimage_set.filter(contents='elevation')
     
-    
\ No newline at end of file
+    
diff --git a/troggle/expo/views_logbooks.py b/troggle/expo/views_logbooks.py
index 72c44e816..513701b99 100644
--- a/troggle/expo/views_logbooks.py
+++ b/troggle/expo/views_logbooks.py
@@ -4,6 +4,7 @@ import troggle.settings as settings
 
 from troggle.parsers.logbooks import LoadLogbookForExpedition
 from troggle.parsers.people import GetPersonExpeditionNameLookup
+from troggle.expo.forms import PersonForm
 
 import search
 import re
@@ -58,3 +59,8 @@ def logbookSearch(request, extra):
     return render_to_response('logbooksearch.html',
                           { 'query_string': query_string, 'found_entries': found_entries, 'settings': settings})
                           #context_instance=RequestContext(request))
+
+def personForm(request,pk):
+    person=Person.objects.get(pk=pk)
+    form=PersonForm(instance=person)
+    return render_to_response('personform.html', {'form':form,'settings':settings})
\ No newline at end of file
diff --git a/troggle/media/css/main2.css b/troggle/media/css/main2.css
index c7c7276b5..fee993c15 100644
--- a/troggle/media/css/main2.css
+++ b/troggle/media/css/main2.css
@@ -62,6 +62,8 @@ div#footer
     margin-right:auto;
 }
 
+#frontPageBanner{ position:relative; width:inherit; height:inherit; }
+
 div.logbookentry
 {
     text-align:left;
diff --git a/troggle/profiles/__init__.py b/troggle/profiles/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/troggle/profiles/urls.py b/troggle/profiles/urls.py
new file mode 100644
index 000000000..05ff9e434
--- /dev/null
+++ b/troggle/profiles/urls.py
@@ -0,0 +1,43 @@
+"""
+URLConf for Django user profile management.
+
+Recommended usage is to use a call to ``include()`` in your project's
+root URLConf to include this URLConf for any URL beginning with
+'/profiles/'.
+
+If the default behavior of the profile views is acceptable to you,
+simply use a line like this in your root URLConf to set up the default
+URLs for profiles::
+
+    (r'^profiles/', include('profiles.urls')),
+
+But if you'd like to customize the behavior (e.g., by passing extra
+arguments to the various views) or split up the URLs, feel free to set
+up your own URL patterns for these views instead. If you do, it's a
+good idea to keep the name ``profiles_profile_detail`` for the pattern
+which points to the ``profile_detail`` view, since several views use
+``reverse()`` with that name to generate a default post-submission
+redirect. If you don't use that name, remember to explicitly pass
+``success_url`` to those views.
+
+"""
+
+from django.conf.urls.defaults import *
+
+from profiles import views
+
+
+urlpatterns = patterns('',
+                       url(r'^create/$',
+                           views.create_profile,
+                           name='profiles_create_profile'),
+                       url(r'^edit/$',
+                           views.edit_profile,
+                           name='profiles_edit_profile'),
+                       url(r'^(?P<username>\w+)/$',
+                           views.profile_detail,
+                           name='profiles_profile_detail'),
+                       url(r'^$',
+                           views.profile_list,
+                           name='profiles_profile_list'),
+                       )
diff --git a/troggle/profiles/utils.py b/troggle/profiles/utils.py
new file mode 100644
index 000000000..faacfcbc1
--- /dev/null
+++ b/troggle/profiles/utils.py
@@ -0,0 +1,45 @@
+"""
+Utility functions for retrieving and generating forms for the
+site-specific user profile model specified in the
+``AUTH_PROFILE_MODULE`` setting.
+
+"""
+
+from django import forms
+from django.conf import settings
+from django.contrib.auth.models import SiteProfileNotAvailable
+from django.db.models import get_model
+
+
+def get_profile_model():
+    """
+    Return the model class for the currently-active user profile
+    model, as defined by the ``AUTH_PROFILE_MODULE`` setting. If that
+    setting is missing, raise
+    ``django.contrib.auth.models.SiteProfileNotAvailable``.
+    
+    """
+    if (not hasattr(settings, 'AUTH_PROFILE_MODULE')) or \
+           (not settings.AUTH_PROFILE_MODULE):
+        raise SiteProfileNotAvailable
+    profile_mod = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))
+    if profile_mod is None:
+        raise SiteProfileNotAvailable
+    return profile_mod
+
+
+def get_profile_form():
+    """
+    Return a form class (a subclass of the default ``ModelForm``)
+    suitable for creating/editing instances of the site-specific user
+    profile model, as defined by the ``AUTH_PROFILE_MODULE``
+    setting. If that setting is missing, raise
+    ``django.contrib.auth.models.SiteProfileNotAvailable``.
+    
+    """
+    profile_mod = get_profile_model()
+    class _ProfileForm(forms.ModelForm):
+        class Meta:
+            model = profile_mod
+            exclude = ('user',) # User will be filled in by the view.
+    return _ProfileForm
diff --git a/troggle/profiles/views.py b/troggle/profiles/views.py
new file mode 100644
index 000000000..c1191655b
--- /dev/null
+++ b/troggle/profiles/views.py
@@ -0,0 +1,340 @@
+"""
+Views for creating, editing and viewing site-specific user profiles.
+
+"""
+
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.urlresolvers import reverse
+from django.http import Http404
+from django.http import HttpResponseRedirect
+from django.shortcuts import get_object_or_404
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.views.generic.list_detail import object_list
+
+from profiles import utils
+
+import troggle.settings as settings
+
+
+
+def create_profile(request, form_class=None, success_url=None,
+                   template_name='profiles/create_profile.html',
+                   extra_context=None):
+    """
+    Create a profile for the current user, if one doesn't already
+    exist.
+    
+    If the user already has a profile, as determined by
+    ``request.user.get_profile()``, a redirect will be issued to the
+    :view:`profiles.views.edit_profile` view. If no profile model has
+    been specified in the ``AUTH_PROFILE_MODULE`` setting,
+    ``django.contrib.auth.models.SiteProfileNotAvailable`` will be
+    raised.
+    
+    **Optional arguments:**
+    
+    ``extra_context``
+        A dictionary of variables to add to the template context. Any
+        callable object in this dictionary will be called to produce
+        the end result which appears in the context.
+
+    ``form_class``
+        The form class to use for validating and creating the user
+        profile. This form class must define a method named
+        ``save()``, implementing the same argument signature as the
+        ``save()`` method of a standard Django ``ModelForm`` (this
+        view will call ``save(commit=False)`` to obtain the profile
+        object, and fill in the user before the final save). If the
+        profile object includes many-to-many relations, the convention
+        established by ``ModelForm`` of using a method named
+        ``save_m2m()`` will be used, and so your form class should
+        also define this method.
+        
+        If this argument is not supplied, this view will use a
+        ``ModelForm`` automatically generated from the model specified
+        by ``AUTH_PROFILE_MODULE``.
+    
+    ``success_url``
+        The URL to redirect to after successful profile creation. If
+        this argument is not supplied, this will default to the URL of
+        :view:`profiles.views.profile_detail` for the newly-created
+        profile object.
+    
+    ``template_name``
+        The template to use when displaying the profile-creation
+        form. If not supplied, this will default to
+        :template:`profiles/create_profile.html`.
+    
+    **Context:**
+    
+    ``form``
+        The profile-creation form.
+    
+    **Template:**
+    
+    ``template_name`` keyword argument, or
+    :template:`profiles/create_profile.html`.
+    
+    """
+    try:
+        profile_obj = request.user.get_profile()
+        return HttpResponseRedirect(reverse('profiles_edit_profile'))
+    except ObjectDoesNotExist:
+        pass
+    
+    #
+    # We set up success_url here, rather than as the default value for
+    # the argument. Trying to do it as the argument's default would
+    # mean evaluating the call to reverse() at the time this module is
+    # first imported, which introduces a circular dependency: to
+    # perform the reverse lookup we need access to profiles/urls.py,
+    # but profiles/urls.py in turn imports this module.
+    #
+    
+    if success_url is None:
+        success_url = reverse('profiles_profile_detail',
+                              kwargs={ 'username': request.user.username })
+    if form_class is None:
+        form_class = utils.get_profile_form()
+    if request.method == 'POST':
+        form = form_class(data=request.POST, files=request.FILES)
+        if form.is_valid():
+            profile_obj = form.save(commit=False)
+            profile_obj.user = request.user
+            profile_obj.save()
+            if hasattr(form, 'save_m2m'):
+                form.save_m2m()
+            return HttpResponseRedirect(success_url)
+    else:
+        form = form_class()
+    
+    if extra_context is None:
+        extra_context = {}
+    context = RequestContext(request)
+    for key, value in extra_context.items():
+        context[key] = callable(value) and value() or value
+    
+    return render_to_response(template_name,
+                              { 'form': form, 'settings':settings },
+                              context_instance=context)
+create_profile = login_required(create_profile)
+
+def edit_profile(request, form_class=None, success_url=None,
+                 template_name='profiles/edit_profile.html',
+                 extra_context=None):
+    """
+    Edit the current user's profile.
+    
+    If the user does not already have a profile (as determined by
+    ``User.get_profile()``), a redirect will be issued to the
+    :view:`profiles.views.create_profile` view; if no profile model
+    has been specified in the ``AUTH_PROFILE_MODULE`` setting,
+    ``django.contrib.auth.models.SiteProfileNotAvailable`` will be
+    raised.
+    
+    **Optional arguments:**
+    
+    ``extra_context``
+        A dictionary of variables to add to the template context. Any
+        callable object in this dictionary will be called to produce
+        the end result which appears in the context.
+
+    ``form_class``
+        The form class to use for validating and editing the user
+        profile. This form class must operate similarly to a standard
+        Django ``ModelForm`` in that it must accept an instance of the
+        object to be edited as the keyword argument ``instance`` to
+        its constructor, and it must implement a method named
+        ``save()`` which will save the updates to the object. If this
+        argument is not specified, this view will use a ``ModelForm``
+        generated from the model specified in the
+        ``AUTH_PROFILE_MODULE`` setting.
+    
+    ``success_url``
+        The URL to redirect to following a successful edit. If not
+        specified, this will default to the URL of
+        :view:`profiles.views.profile_detail` for the profile object
+        being edited.
+    
+    ``template_name``
+        The template to use when displaying the profile-editing
+        form. If not specified, this will default to
+        :template:`profiles/edit_profile.html`.
+    
+    **Context:**
+    
+    ``form``
+        The form for editing the profile.
+        
+    ``profile``
+         The user's current profile.
+    
+    **Template:**
+    
+    ``template_name`` keyword argument or
+    :template:`profiles/edit_profile.html`.
+    
+    """
+    try:
+        profile_obj = request.user.get_profile()
+    except ObjectDoesNotExist:
+        return HttpResponseRedirect(reverse('profiles_create_profile'))
+    
+    #
+    # See the comment in create_profile() for discussion of why
+    # success_url is set up here, rather than as a default value for
+    # the argument.
+    #
+    
+    if success_url is None:
+        success_url = reverse('profiles_profile_detail',
+                              kwargs={ 'username': request.user.username })
+    if form_class is None:
+        form_class = utils.get_profile_form()
+    if request.method == 'POST':
+        form = form_class(data=request.POST, files=request.FILES, instance=profile_obj)
+        if form.is_valid():
+            form.save()
+            return HttpResponseRedirect(success_url)
+    else:
+        form = form_class(instance=profile_obj)
+    
+    if extra_context is None:
+        extra_context = {}
+    context = RequestContext(request)
+    for key, value in extra_context.items():
+        context[key] = callable(value) and value() or value
+    
+    return render_to_response(template_name,
+                              { 'form': form,
+                                'profile': profile_obj, },
+                              context_instance=context)
+edit_profile = login_required(edit_profile)
+
+def profile_detail(request, username, public_profile_field=None,
+                   template_name='profiles/profile_detail.html',
+                   extra_context=None):
+    """
+    Detail view of a user's profile.
+    
+    If no profile model has been specified in the
+    ``AUTH_PROFILE_MODULE`` setting,
+    ``django.contrib.auth.models.SiteProfileNotAvailable`` will be
+    raised.
+    
+    If the user has not yet created a profile, ``Http404`` will be
+    raised.
+    
+    **Required arguments:**
+    
+    ``username``
+        The username of the user whose profile is being displayed.
+    
+    **Optional arguments:**
+
+    ``extra_context``
+        A dictionary of variables to add to the template context. Any
+        callable object in this dictionary will be called to produce
+        the end result which appears in the context.
+
+    ``public_profile_field``
+        The name of a ``BooleanField`` on the profile model; if the
+        value of that field on the user's profile is ``False``, the
+        ``profile`` variable in the template will be ``None``. Use
+        this feature to allow users to mark their profiles as not
+        being publicly viewable.
+        
+        If this argument is not specified, it will be assumed that all
+        users' profiles are publicly viewable.
+    
+    ``template_name``
+        The name of the template to use for displaying the profile. If
+        not specified, this will default to
+        :template:`profiles/profile_detail.html`.
+    
+    **Context:**
+    
+    ``profile``
+        The user's profile, or ``None`` if the user's profile is not
+        publicly viewable (see the description of
+        ``public_profile_field`` above).
+    
+    **Template:**
+    
+    ``template_name`` keyword argument or
+    :template:`profiles/profile_detail.html`.
+    
+    """
+    user = get_object_or_404(User, username=username)
+    try:
+        profile_obj = user.get_profile()
+    except ObjectDoesNotExist:
+        raise Http404
+    if public_profile_field is not None and \
+       not getattr(profile_obj, public_profile_field):
+        profile_obj = None
+    
+    if extra_context is None:
+        extra_context = {}
+    context = RequestContext(request)
+    for key, value in extra_context.items():
+        context[key] = callable(value) and value() or value
+    
+    return render_to_response(template_name,
+                              { 'profile': profile_obj },
+                              context_instance=context)
+
+def profile_list(request, public_profile_field=None,
+                 template_name='profiles/profile_list.html', **kwargs):
+    """
+    A list of user profiles.
+    
+    If no profile model has been specified in the
+    ``AUTH_PROFILE_MODULE`` setting,
+    ``django.contrib.auth.models.SiteProfileNotAvailable`` will be
+    raised.
+
+    **Optional arguments:**
+
+    ``public_profile_field``
+        The name of a ``BooleanField`` on the profile model; if the
+        value of that field on a user's profile is ``False``, that
+        profile will be excluded from the list. Use this feature to
+        allow users to mark their profiles as not being publicly
+        viewable.
+        
+        If this argument is not specified, it will be assumed that all
+        users' profiles are publicly viewable.
+    
+    ``template_name``
+        The name of the template to use for displaying the profiles. If
+        not specified, this will default to
+        :template:`profiles/profile_list.html`.
+
+    Additionally, all arguments accepted by the
+    :view:`django.views.generic.list_detail.object_list` generic view
+    will be accepted here, and applied in the same fashion, with one
+    exception: ``queryset`` will always be the ``QuerySet`` of the
+    model specified by the ``AUTH_PROFILE_MODULE`` setting, optionally
+    filtered to remove non-publicly-viewable proiles.
+    
+    **Context:**
+    
+    Same as the :view:`django.views.generic.list_detail.object_list`
+    generic view.
+    
+    **Template:**
+    
+    ``template_name`` keyword argument or
+    :template:`profiles/profile_list.html`.
+    
+    """
+    profile_model = utils.get_profile_model()
+    queryset = profile_model._default_manager.all()
+    if public_profile_field is not None:
+        queryset = queryset.filter(**{ public_profile_field: True })
+    kwargs['queryset'] = queryset
+    return object_list(request, template_name=template_name, **kwargs)
diff --git a/troggle/registration/__init__.py b/troggle/registration/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/troggle/registration/admin.py b/troggle/registration/admin.py
new file mode 100644
index 000000000..3f36c1807
--- /dev/null
+++ b/troggle/registration/admin.py
@@ -0,0 +1,11 @@
+from django.contrib import admin
+
+from registration.models import RegistrationProfile
+
+
+class RegistrationAdmin(admin.ModelAdmin):
+    list_display = ('__unicode__', 'activation_key_expired')
+    search_fields = ('user__username', 'user__first_name')
+
+
+admin.site.register(RegistrationProfile, RegistrationAdmin)
diff --git a/troggle/registration/forms.py b/troggle/registration/forms.py
new file mode 100644
index 000000000..f2298aca0
--- /dev/null
+++ b/troggle/registration/forms.py
@@ -0,0 +1,134 @@
+"""
+Forms and validation code for user registration.
+
+"""
+
+
+from django.contrib.auth.models import User
+from django import forms
+from django.utils.translation import ugettext_lazy as _
+
+from registration.models import RegistrationProfile
+
+
+# I put this on all required fields, because it's easier to pick up
+# on them with CSS or JavaScript if they have a class of "required"
+# in the HTML. Your mileage may vary. If/when Django ticket #3515
+# lands in trunk, this will no longer be necessary.
+attrs_dict = { 'class': 'required' }
+
+
+class RegistrationForm(forms.Form):
+    """
+    Form for registering a new user account.
+    
+    Validates that the requested username is not already in use, and
+    requires the password to be entered twice to catch typos.
+    
+    Subclasses should feel free to add any additional validation they
+    need, but should either preserve the base ``save()`` or implement
+    a ``save()`` method which returns a ``User``.
+    
+    """
+    username = forms.RegexField(regex=r'^\w+$',
+                                max_length=30,
+                                widget=forms.TextInput(attrs=attrs_dict),
+                                label=_(u'username'))
+    email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
+                                                               maxlength=75)),
+                             label=_(u'email address'))
+    password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
+                                label=_(u'password'))
+    password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False),
+                                label=_(u'password (again)'))
+    
+    def clean_username(self):
+        """
+        Validate that the username is alphanumeric and is not already
+        in use.
+        
+        """
+        try:
+            user = User.objects.get(username__iexact=self.cleaned_data['username'])
+        except User.DoesNotExist:
+            return self.cleaned_data['username']
+        raise forms.ValidationError(_(u'This username is already taken. Please choose another.'))
+
+    def clean(self):
+        """
+        Verifiy that the values entered into the two password fields
+        match. Note that an error here will end up in
+        ``non_field_errors()`` because it doesn't apply to a single
+        field.
+        
+        """
+        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
+            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
+                raise forms.ValidationError(_(u'You must type the same password each time'))
+        return self.cleaned_data
+    
+    def save(self):
+        """
+        Create the new ``User`` and ``RegistrationProfile``, and
+        returns the ``User`` (by calling
+        ``RegistrationProfile.objects.create_inactive_user()``).
+        
+        """
+        new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],
+                                                                    password=self.cleaned_data['password1'],
+                                                                    email=self.cleaned_data['email'])
+        return new_user
+
+
+class RegistrationFormTermsOfService(RegistrationForm):
+    """
+    Subclass of ``RegistrationForm`` which adds a required checkbox
+    for agreeing to a site's Terms of Service.
+    
+    """
+    tos = forms.BooleanField(widget=forms.CheckboxInput(attrs=attrs_dict),
+                             label=_(u'I have read and agree to the Terms of Service'),
+                             error_messages={ 'required': u"You must agree to the terms to register" })
+
+
+class RegistrationFormUniqueEmail(RegistrationForm):
+    """
+    Subclass of ``RegistrationForm`` which enforces uniqueness of
+    email addresses.
+    
+    """
+    def clean_email(self):
+        """
+        Validate that the supplied email address is unique for the
+        site.
+        
+        """
+        if User.objects.filter(email__iexact=self.cleaned_data['email']):
+            raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.'))
+        return self.cleaned_data['email']
+
+
+class RegistrationFormNoFreeEmail(RegistrationForm):
+    """
+    Subclass of ``RegistrationForm`` which disallows registration with
+    email addresses from popular free webmail services; moderately
+    useful for preventing automated spam registrations.
+    
+    To change the list of banned domains, subclass this form and
+    override the attribute ``bad_domains``.
+    
+    """
+    bad_domains = ['aim.com', 'aol.com', 'email.com', 'gmail.com',
+                   'googlemail.com', 'hotmail.com', 'hushmail.com',
+                   'msn.com', 'mail.ru', 'mailinator.com', 'live.com']
+    
+    def clean_email(self):
+        """
+        Check the supplied email address against a list of known free
+        webmail domains.
+        
+        """
+        email_domain = self.cleaned_data['email'].split('@')[1]
+        if email_domain in self.bad_domains:
+            raise forms.ValidationError(_(u'Registration using free email addresses is prohibited. Please supply a different email address.'))
+        return self.cleaned_data['email']
diff --git a/troggle/registration/locale/ar/LC_MESSAGES/django.mo b/troggle/registration/locale/ar/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..07bc79f12
Binary files /dev/null and b/troggle/registration/locale/ar/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/ar/LC_MESSAGES/django.po b/troggle/registration/locale/ar/LC_MESSAGES/django.po
new file mode 100644
index 000000000..dd61869d3
--- /dev/null
+++ b/troggle/registration/locale/ar/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "اسم المستخدم"
+
+#: forms.py:41
+msgid "email address"
+msgstr "عنوان البريد الالكتروني"
+
+#: forms.py:43
+msgid "password"
+msgstr "كلمة المرور"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "تأكيد كلمة المرور"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "يمكن أن يحتوي اسم المستخدم على احرف، ارقام وشرطات سطرية فقط"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "اسم المستخدم مسجل مسبقا. يرجى اختيار اسم اخر."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "يجب ادخال كلمة المرور مطابقة كل مرة"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "أقر بقراءة والموافقة على شروط الخدمة"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "يجب الموافقة على الشروط للتسجيل"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "عنوان البريد الالكتروني مسجل مسبقا. يرجى تزويد عنوان بريد الكتروني مختلف."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "يمنع التسجيل باستخدام عناوين بريد الكترونية مجانية. يرجى تزويد عنوان بريد الكتروني مختلف."
+
+#: models.py:188
+msgid "user"
+msgstr "مستخدم"
+
+#: models.py:189
+msgid "activation key"
+msgstr "رمز التفعيل"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "ملف التسجيل الشخصي"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "ملفات التسجيل الشخصية"
diff --git a/troggle/registration/locale/bg/LC_MESSAGES/django.mo b/troggle/registration/locale/bg/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..be9adf4d3
Binary files /dev/null and b/troggle/registration/locale/bg/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/bg/LC_MESSAGES/django.po b/troggle/registration/locale/bg/LC_MESSAGES/django.po
new file mode 100644
index 000000000..5089ec17d
--- /dev/null
+++ b/troggle/registration/locale/bg/LC_MESSAGES/django.po
@@ -0,0 +1,78 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2008-03-05 12:37+0200\n"
+"Last-Translator: Vladislav <vladislav.mitov@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Bookmarks: -1,-1,-1,-1,10,-1,-1,-1,-1,-1\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "Потребителско име "
+
+#: forms.py:41
+msgid "email address"
+msgstr "Електронна поща"
+
+#: forms.py:43
+msgid "password"
+msgstr "Парола"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "Парола (проверка)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Потребителските имена могат да съдържат букви, цифри и подчертавки"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Потребителското име е заето. Моля изберето друго."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Грешка при проверка на паролата."
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Прочел съм и съм съгласен с условията за експлоатация"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Трябва да сте съгласни с условията за да се регистрирате."
+
+#: forms.py:124
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "Адреса на електронната поща е използван. Моля въведете друг адрес."
+
+#: forms.py:149
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "Регистрациите с безплатни адреси е забранен. Моля въведете различен адрес за електронна поща"
+
+#: models.py:188
+msgid "user"
+msgstr "Потребител"
+
+#: models.py:189
+msgid "activation key"
+msgstr "Ключ за активация"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "регистрационен профил"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "регистрационни профили"
+
diff --git a/troggle/registration/locale/de/LC_MESSAGES/django.mo b/troggle/registration/locale/de/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..b9bc1faa0
Binary files /dev/null and b/troggle/registration/locale/de/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/de/LC_MESSAGES/django.po b/troggle/registration/locale/de/LC_MESSAGES/django.po
new file mode 100644
index 000000000..96e00ee23
--- /dev/null
+++ b/troggle/registration/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,85 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Jannis Leidel <jannis@leidel.info>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: django-registration 0.3 \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2007-09-29 16:50+0200\n"
+"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
+"Language-Team: Deutsch <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "Benutzername"
+
+#: forms.py:41
+msgid "email address"
+msgstr "E-Mail-Adresse"
+
+#: forms.py:43
+msgid "password"
+msgstr "Passwort"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "Passwort (wiederholen)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Benutzernamen können nur Buchstaben, Zahlen und Unterstriche enthalten"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Dieser Benutzername ist schon vergeben. Bitte einen anderen wählen."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Bitte das gleiche Passwort zur Überprüfung nochmal eingeben"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Ich habe die Nutzungsvereinbarung gelesen und stimme ihr zu"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Sie müssen der Nutzungsvereinbarung zustimmen, um sich zu registrieren"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr ""
+"Diese E-Mail-Adresse wird schon genutzt. Bitte geben Sie eine andere "
+"E-Mail-Adresse an."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+"Die Registrierung mit einer kostenlosen E-Mail-Adresse ist untersagt. Bitte "
+"geben Sie eine andere E-Mail-Adresse an."
+
+#: models.py:188
+msgid "user"
+msgstr "Benutzer"
+
+#: models.py:189
+msgid "activation key"
+msgstr "Aktivierungsschlüssel"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "Registrierungsprofil"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "Registrierungsprofile"
diff --git a/troggle/registration/locale/el/LC_MESSAGES/django.mo b/troggle/registration/locale/el/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..acc972683
Binary files /dev/null and b/troggle/registration/locale/el/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/el/LC_MESSAGES/django.po b/troggle/registration/locale/el/LC_MESSAGES/django.po
new file mode 100644
index 000000000..cd38eb1b4
--- /dev/null
+++ b/troggle/registration/locale/el/LC_MESSAGES/django.po
@@ -0,0 +1,84 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Panos Laganakos <panos.laganakos@gmail.com>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2007-11-14 21:50+0200\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "όνομα χρήστη"
+
+#: forms.py:41
+msgid "email address"
+msgstr "διεύθυνση ηλεκτρονικού ταχυδρομείου"
+
+#: forms.py:43
+msgid "password"
+msgstr "συνθηματικό"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "συνθηματικό (ξανά)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Τα ονόματα χρηστών μπορούν να περιλαμβάνουν μόνο γράμματα, αριθμούς και υπογραμμίσεις"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Αυτό το όνομα χρήστη χρησιμοποίειται ήδη. Παρακαλώ διαλέξτε ένα άλλο."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Πρέπει να εισάγετε το ίδιο συνθηματικό κάθε φορά"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Διάβασα και συμφωνώ με τους Όρους της Υπηρεσίας"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Πρέπει να συμφωνείται με τους όρους για να εγγραφείτε"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr ""
+"Η συγκεκριμένη διεύθυνση ηλεκτρονικού ταχυδρομείου χρησιμοποιείται ήδη. "
+"Παρακαλώ δώστε κάποια άλλη."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+"Η εγγραφή μέσω δωρεάν διευθύνσεων ηλεκτρονικού ταχυδρομείου απαγορεύεται. ""Παρακαλώ δώστε κάποια άλλη."
+
+#: models.py:188
+msgid "user"
+msgstr "χρήστης"
+
+#: models.py:189
+msgid "activation key"
+msgstr "κλειδί ενεργοποίησης"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "προφίλ εγγραφής"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "προφίλ εγγραφών"
diff --git a/troggle/registration/locale/en/LC_MESSAGES/django.mo b/troggle/registration/locale/en/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..4728fe062
Binary files /dev/null and b/troggle/registration/locale/en/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/en/LC_MESSAGES/django.po b/troggle/registration/locale/en/LC_MESSAGES/django.po
new file mode 100644
index 000000000..37bc9e2ff
--- /dev/null
+++ b/troggle/registration/locale/en/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr ""
+
+#: forms.py:41
+msgid "email address"
+msgstr ""
+
+#: forms.py:43
+msgid "password"
+msgstr ""
+
+#: forms.py:45
+msgid "password (again)"
+msgstr ""
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr ""
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr ""
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr ""
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr ""
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr ""
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr ""
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+
+#: models.py:188
+msgid "user"
+msgstr ""
+
+#: models.py:189
+msgid "activation key"
+msgstr ""
+
+#: models.py:194
+msgid "registration profile"
+msgstr ""
+
+#: models.py:195
+msgid "registration profiles"
+msgstr ""
diff --git a/troggle/registration/locale/es/LC_MESSAGES/django.mo b/troggle/registration/locale/es/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..3872adf0a
Binary files /dev/null and b/troggle/registration/locale/es/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/es/LC_MESSAGES/django.po b/troggle/registration/locale/es/LC_MESSAGES/django.po
new file mode 100644
index 000000000..ba0384fe5
--- /dev/null
+++ b/troggle/registration/locale/es/LC_MESSAGES/django.po
@@ -0,0 +1,85 @@
+# Spanish translation for django-registration.
+# Copyright (C) 2007, James Bennet
+# This file is distributed under the same license as the registration package.
+# Ernesto Rico Schmidt <e.rico.schmidt@gmail.com>, 2008.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: django-registration 0.3 \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-03-11 00:19-0400\n"
+"PO-Revision-Date: 2008-03-11 00:19-0400\n"
+"Last-Translator: Ernesto Rico Schmidt <e.rico.schmidt@gmail.com>\n"
+"Language-Team: Español <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "nombre de usuario"
+
+#: forms.py:41
+msgid "email address"
+msgstr "dirección de coreo electrónico"
+
+#: forms.py:43
+msgid "password"
+msgstr "contraseña"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "contraseña (otra vez)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Los nombres de usuarios sólo pueden contener letras, números y guiones bajos"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Este nombre de usuario ya está ocupado. Por favor escoge otro"
+
+#: forms.py:71
+msgid "You must type the same password each time"
+msgstr "Tienes que introducir la misma contraseña cada vez"
+
+#: forms.py:100
+msgid "I have read and agree to the Terms of Service"
+msgstr "He leído y acepto los términos de servicio"
+
+#: forms.py:109
+msgid "You must agree to the terms to register"
+msgstr "Tienes que aceptar los términos para registrarte"
+
+#: forms.py:128
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr ""
+"La dirección de correo electrónico ya está siendo usada. Por favor"
+"proporciona otra dirección."
+
+#: forms.py:153
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+"El registro usando una dirección de correo electrónico gratis está prohibido."
+"Por favor proporciona otra dirección."
+
+#: models.py:188
+msgid "user"
+msgstr "usuario"
+
+#: models.py:189
+msgid "activation key"
+msgstr "clave de activación"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "perfil de registro"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "perfiles de registro"
diff --git a/troggle/registration/locale/es_AR/LC_MESSAGES/django.mo b/troggle/registration/locale/es_AR/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..ce8b4e56c
Binary files /dev/null and b/troggle/registration/locale/es_AR/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/es_AR/LC_MESSAGES/django.po b/troggle/registration/locale/es_AR/LC_MESSAGES/django.po
new file mode 100644
index 000000000..fb746b5b9
--- /dev/null
+++ b/troggle/registration/locale/es_AR/LC_MESSAGES/django.po
@@ -0,0 +1,83 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2008 Leonardo Manuel Rocha
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <l e o m a r o at g m a i l dot c o m>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "nombre de usuario"
+
+#: forms.py:41
+msgid "email address"
+msgstr "dirección de e-mail"
+
+#: forms.py:43
+msgid "password"
+msgstr "contraseña"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "contraseña (nuevamente)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "El nombre de usuario solo puede contener letras, números y guiones bajos"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Ese nombre de usuario ya está asignado. Por favor elija otro."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Debe tipear la misma contraseña cada vez"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "He leído y estoy de acuerdo con las Condiciones de Servicio"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Debe estar de acuerdo con las Condiciones para poder registrarse"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Esa dirección de e-mail ya está en uso. Por favor provea otra "
+"dirección."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "La registración con un e-mail gratuito está prohibida. Por favor "
+"de una dirección de e-mail diferente."
+
+#: models.py:188
+msgid "user"
+msgstr "usuario"
+
+#: models.py:189
+msgid "activation key"
+msgstr "clave de activación"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "perfil de registro"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "perfiles de registro"
diff --git a/troggle/registration/locale/fr/LC_MESSAGES/django.mo b/troggle/registration/locale/fr/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..f8911c7ec
Binary files /dev/null and b/troggle/registration/locale/fr/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/fr/LC_MESSAGES/django.po b/troggle/registration/locale/fr/LC_MESSAGES/django.po
new file mode 100644
index 000000000..34b520b8b
--- /dev/null
+++ b/troggle/registration/locale/fr/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Samuel Adam <samuel.adam@gmail.com>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: django-registration 0.3 \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2007-09-20 10:30+0100\n"
+"Last-Translator: Samuel Adam <samuel.adam@gmail.com>\n"
+"Language-Team: Français <fr@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "pseudo"
+
+#: forms.py:41
+msgid "email address"
+msgstr "adresse email"
+
+#: forms.py:43
+msgid "password"
+msgstr "mot de passe"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "mot de passe (vérification)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Le pseudo ne peut contenir que des lettres, chiffres et le caractère souligné."
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Ce pseudo est déjà utilisé. Veuillez en choisir un autre."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Veuillez indiquer le même mot de passe dans les deux champs"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "J'ai lu et accepté les Conditions Générales d'Utilisation"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Vous devez accepter les conditions d'utilisation pour vous inscrire"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Cette adresse email est déjà utilisée. Veuillez en indiquer une autre."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "L'inscription avec une adresse email d'un compte gratuit est interdite. Veuillez en indiquer une autre."
+
+#: models.py:188
+msgid "user"
+msgstr "utilisateur"
+
+#: models.py:189
+msgid "activation key"
+msgstr "clé d'activation"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "profil d'inscription"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "profils d'inscription"
diff --git a/troggle/registration/locale/he/LC_MESSAGES/django.mo b/troggle/registration/locale/he/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..be9365032
Binary files /dev/null and b/troggle/registration/locale/he/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/he/LC_MESSAGES/django.po b/troggle/registration/locale/he/LC_MESSAGES/django.po
new file mode 100644
index 000000000..5567e0863
--- /dev/null
+++ b/troggle/registration/locale/he/LC_MESSAGES/django.po
@@ -0,0 +1,86 @@
+# translation of registration.
+# Copyright (C) 2008 THE registration'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the registration package.
+# <>, 2008.
+# , fuzzy
+#  <>, 2008.
+# 
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: registration\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-02-10 02:01+0200\n"
+"PO-Revision-Date: 2008-02-10 02:05+0200\n"
+"Last-Translator: Meir Kriheli <meir@mksoft.co.il>\n"
+"Language-Team: Hebrew\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit"
+
+#: forms.py:38
+msgid "username"
+msgstr "שם משתמש"
+
+#: forms.py:41
+msgid "email address"
+msgstr "דואר אלקטרוני"
+
+#: forms.py:43
+msgid "password"
+msgstr "סיסמה"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "סיסמה (שוב)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "שמות משתמש יכולים להכיל רק אותיות, ספרות וקווים תחתונים"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "שם המשתמש תפוס כבר. נא לבחור אחר."
+
+#: forms.py:64
+msgid "You must type the same password each time"
+msgstr "יש להקליד את אותה הסיסמה פעמיים"
+
+#: forms.py:93
+msgid "I have read and agree to the Terms of Service"
+msgstr "קראתי והסכמתי לתנאי השימוש"
+
+#: forms.py:102
+msgid "You must agree to the terms to register"
+msgstr "עליך להסכים לתנאי השימוש"
+
+#: forms.py:121
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr ""
+"כתובת הדואר האלקטרוני תפוסה כבר. נא לספק כתובת דואר אחרת."
+
+#: forms.py:146
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+"הרישום בעזרת תיבת דואר אלקטרוני חינמית אסור. נא לספק כתובת אחרת."
+
+#: models.py:188
+msgid "user"
+msgstr "משתמש"
+
+#: models.py:189
+msgid "activation key"
+msgstr "מפתח הפעלה"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "פרופיל רישום"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "פרופילי רישום"
+
diff --git a/troggle/registration/locale/it/LC_MESSAGES/django.mo b/troggle/registration/locale/it/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..83ec9ddb1
Binary files /dev/null and b/troggle/registration/locale/it/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/it/LC_MESSAGES/django.po b/troggle/registration/locale/it/LC_MESSAGES/django.po
new file mode 100644
index 000000000..00129b044
--- /dev/null
+++ b/troggle/registration/locale/it/LC_MESSAGES/django.po
@@ -0,0 +1,82 @@
+# translation of django.po to Italiano
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Nicola Larosa <nico@tekNico.net>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: django\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2008-05-27 15:05+0200\n"
+"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
+"Language-Team: Italiano\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms:  nplurals=2; plural=(n != 1);\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "nome utente"
+
+#: forms.py:41
+msgid "email address"
+msgstr "indirizzo email"
+
+#: forms.py:43
+msgid "password"
+msgstr "password"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "password (di nuovo)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "I nomi utente possono contenere solo lettere, numeri e sottolineature"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Questo nome utente è già usato. Scegline un altro."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Bisogna inserire la stessa password ogni volta"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Dichiaro di aver letto e di approvare le Condizioni di Servizio"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Per registrarsi bisogna approvare le condizioni"
+
+#: forms.py:124
+msgid "This email address is already in use. Please supply a different email "
+"address."
+msgstr "Questo indirizzo email è già in uso. Inserisci un altro indirizzo email."
+
+#: forms.py:149
+msgid "Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "La registrazione con indirizzi email gratis non è permessa. "
+"Inserisci un altro indirizzo email."
+
+#: models.py:188
+msgid "user"
+msgstr "utente"
+
+#: models.py:189
+msgid "activation key"
+msgstr "chiave di attivazione"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "profilo di registrazione"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "profili di registrazione"
+
diff --git a/troggle/registration/locale/ja/LC_MESSAGES/django.mo b/troggle/registration/locale/ja/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..e0332b0e7
Binary files /dev/null and b/troggle/registration/locale/ja/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/ja/LC_MESSAGES/django.po b/troggle/registration/locale/ja/LC_MESSAGES/django.po
new file mode 100644
index 000000000..afaaf948b
--- /dev/null
+++ b/troggle/registration/locale/ja/LC_MESSAGES/django.po
@@ -0,0 +1,78 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Shinya Okano <xxshss@yahoo.co.jp>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: django-registration 0.4 \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2008-01-31 10:20+0900\n"
+"Last-Translator: Shinya Okano <xxshss@yahoo.co.jp>\n"
+"Language-Team: Japanese <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "ユーザ名"
+
+#: forms.py:41
+msgid "email address"
+msgstr "メールアドレス"
+
+#: forms.py:43
+msgid "password"
+msgstr "パスワード"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "パスワード (確認)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "ユーザ名には半角英数とアンダースコアのみが使用できます。"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "このユーザ名は既に使用されています。他のユーザ名を指定してください。"
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "同じパスワードを入力する必要があります。"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "サービス利用規約を読み、同意します。"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "登録するためには規約に同意する必要があります。"
+
+#: forms.py:124
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "このメールアドレスは既に使用されています。他のメールアドレスを指定して下さい。"
+
+#: forms.py:149
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "自由なメールアドレスを使用した登録は禁止されています。他のメールアドレスを指定してください。"
+
+#: models.py:188
+msgid "user"
+msgstr "ユーザ"
+
+#: models.py:189
+msgid "activation key"
+msgstr "アクティベーションキー"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "登録プロファイル"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "登録プロファイル"
+
diff --git a/troggle/registration/locale/nl/LC_MESSAGES/django.mo b/troggle/registration/locale/nl/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..9e84eb3ed
Binary files /dev/null and b/troggle/registration/locale/nl/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/nl/LC_MESSAGES/django.po b/troggle/registration/locale/nl/LC_MESSAGES/django.po
new file mode 100644
index 000000000..03cb2e5db
--- /dev/null
+++ b/troggle/registration/locale/nl/LC_MESSAGES/django.po
@@ -0,0 +1,77 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: registration\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-08-14 13:25+0200\n"
+"PO-Revision-Date: 2008-08-14 13:25+0200\n"
+"Last-Translator: Joost Cassee <joost@cassee.net>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "gebruikersnaam"
+
+#: forms.py:41
+msgid "email address"
+msgstr "e-mail adres"
+
+#: forms.py:43
+msgid "password"
+msgstr "wachtwoord"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "wachtwoord (opnieuw)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Gebruikersnamen kunnen alleen letters, nummer en liggende streepjes bevatten."
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Deze gebruikersnaam is reeds in gebruik. Kiest u alstublieft een andere gebruikersnaam."
+
+#: forms.py:71
+msgid "You must type the same password each time"
+msgstr "U moet twee maal hetzelfde wachtwoord typen."
+
+#: forms.py:100
+msgid "I have read and agree to the Terms of Service"
+msgstr "Ik heb de servicevoorwaarden gelezen en ga akkoord."
+
+#: forms.py:109
+msgid "You must agree to the terms to register"
+msgstr "U moet akkoord gaan met de servicevoorwaarden om u te registreren."
+
+#: forms.py:125
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "Dit e-mail adres is reeds in gebruik. Kiest u alstublieft een ander e-mail adres."
+
+#: forms.py:151
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "U kunt u niet registreren met een gratis e-mail adres. Kiest u alstublieft een ander e-mail adres."
+
+#: models.py:191
+msgid "user"
+msgstr "gebruiker"
+
+#: models.py:192
+msgid "activation key"
+msgstr "activatiecode"
+
+#: models.py:197
+msgid "registration profile"
+msgstr "registratieprofiel"
+
+#: models.py:198
+msgid "registration profiles"
+msgstr "registratieprofielen"
diff --git a/troggle/registration/locale/pl/LC_MESSAGES/django.mo b/troggle/registration/locale/pl/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..1f2a22886
Binary files /dev/null and b/troggle/registration/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/pl/LC_MESSAGES/django.po b/troggle/registration/locale/pl/LC_MESSAGES/django.po
new file mode 100644
index 000000000..498fd5b6b
--- /dev/null
+++ b/troggle/registration/locale/pl/LC_MESSAGES/django.po
@@ -0,0 +1,84 @@
+# Polish translation for django-registration.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the django-registration package.
+# Jarek Zgoda <jarek.zgoda@gmail.com>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2007-12-15 12:45+0100\n"
+"Last-Translator: Jarek Zgoda <jarek.zgoda@gmail.com>\n"
+"Language-Team: Polish <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "nazwa użytkownika"
+
+#: forms.py:41
+msgid "email address"
+msgstr "adres email"
+
+#: forms.py:43
+msgid "password"
+msgstr "hasło"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "hasło (ponownie)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr ""
+"Nazwa użytkownika może zawierać tylko litery, cyfry i znaki podkreślenia"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Ta nazwa użytkownika jest już zajęta. Wybierz inną."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Musisz wpisać to samo hasło w obu polach"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Przeczytałem regulamin i akceptuję go"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Musisz zaakceptować regulamin, aby się zarejestrować"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Ten adres email jest już używany. Użyj innego adresu email."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr ""
+"Nie ma możliwości rejestracji przy użyciu darmowego adresu email. Użyj "
+"innego adresu email."
+
+#: models.py:188
+msgid "user"
+msgstr "użytkownik"
+
+#: models.py:189
+msgid "activation key"
+msgstr "klucz aktywacyjny"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "profil rejestracji"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "profile rejestracji"
diff --git a/troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..e81b6207b
Binary files /dev/null and b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po
new file mode 100644
index 000000000..9e8addb6f
--- /dev/null
+++ b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "usuário"
+
+#: forms.py:41
+msgid "email address"
+msgstr "endereço de email"
+
+#: forms.py:43
+msgid "password"
+msgstr ""
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "senha (novamente)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Nomes de usuário apenas podem conter letras, números, e underscore"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Este nome de usuário já existe. Por favor, escolha outro."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Você deve escrever a mesma senha nos dois campos"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Eu lí e concordo com os Termos de Uso do serviço"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Você deve concordar com os termos para registrar-se"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Este endereço de email já está em uso. Por favor, informe um endereço de email diferente."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "Registrar-se com contas de email gratuitos está proibido. Por favor, informe um endereço de email diferente."
+
+#: models.py:188
+msgid "user"
+msgstr "usuário"
+
+#: models.py:189
+msgid "activation key"
+msgstr "chave de ativação"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "profile de registro"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "profiles de registro"
diff --git a/troggle/registration/locale/ru/LC_MESSAGES/django.mo b/troggle/registration/locale/ru/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..b6eb3f11e
Binary files /dev/null and b/troggle/registration/locale/ru/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/ru/LC_MESSAGES/django.po b/troggle/registration/locale/ru/LC_MESSAGES/django.po
new file mode 100644
index 000000000..8b0c30917
--- /dev/null
+++ b/troggle/registration/locale/ru/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "имя пользователя"
+
+#: forms.py:41
+msgid "email address"
+msgstr "адрес электронной почты"
+
+#: forms.py:43
+msgid "password"
+msgstr "пароль"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "пароль (верификация)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Имя пользователя может содержать только буквы, цифры и подчеркивания"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Такое имя пользователя уже есть. Пожалуйста, выберите другое."
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "Вы должны вводить один и тот же пароль каждый раз"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "Я прочитал и согласен с Правилами Использования"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "Вы должны согласиться с Правилами для регистрации"
+
+#: forms.py:124
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Этот адрес электронной почты уже используется. Пожалуйста, введите другой адрес."
+
+#: forms.py:149
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "Регистрация с использованием свободных почтовых серверов запрещена. Пожалуйста, введите другой адрес электронной почты."
+
+#: models.py:188
+msgid "user"
+msgstr "пользователь"
+
+#: models.py:189
+msgid "activation key"
+msgstr "ключ активации"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "профиль регистрации"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "профили регистрации"
diff --git a/troggle/registration/locale/sr/LC_MESSAGES/django.mo b/troggle/registration/locale/sr/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..169932655
Binary files /dev/null and b/troggle/registration/locale/sr/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/sr/LC_MESSAGES/django.po b/troggle/registration/locale/sr/LC_MESSAGES/django.po
new file mode 100644
index 000000000..4fa699c55
--- /dev/null
+++ b/troggle/registration/locale/sr/LC_MESSAGES/django.po
@@ -0,0 +1,80 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: django-registration trunk\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-04-05 13:51+0200\n"
+"PO-Revision-Date: 2008-04-05 14:00+0100\n"
+"Last-Translator: Nebojsa Djordjevic <djnesh@gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Serbian\n"
+"X-Poedit-Country: YUGOSLAVIA\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "korisničko ime"
+
+#: forms.py:41
+msgid "email address"
+msgstr "email adresa"
+
+#: forms.py:43
+msgid "password"
+msgstr "šifra"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "šifra (ponovo)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Korisničko ime može da se sastoji samo od slova, brojeva i donje crte (\"_\")"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "Korisničko ime je već zauzeto. Izaberite drugo."
+
+#: forms.py:71
+msgid "You must type the same password each time"
+msgstr "Unete šifre se ne slažu"
+
+#: forms.py:100
+msgid "I have read and agree to the Terms of Service"
+msgstr "Pročitao sam i slažem se sa uslovima korišćenja"
+
+#: forms.py:109
+msgid "You must agree to the terms to register"
+msgstr "Morate se složiti sa uslovima korišćenja da bi ste se registrovali"
+
+#: forms.py:128
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "Ova e-mail adresa je već u upotrebi. Morate koristiti drugu e-mail adresu."
+
+#: forms.py:153
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "Registracija korišćenjem besplatnig e-mail adresa je zabranjena. Morate uneti drugu e-mail adresu."
+
+#: models.py:188
+msgid "user"
+msgstr "korisnik"
+
+#: models.py:189
+msgid "activation key"
+msgstr "aktivacioni ključ"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "registracioni profil"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "registracioni profili"
+
diff --git a/troggle/registration/locale/sv/LC_MESSAGES/django.mo b/troggle/registration/locale/sv/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..50eca67e2
Binary files /dev/null and b/troggle/registration/locale/sv/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/sv/LC_MESSAGES/django.po b/troggle/registration/locale/sv/LC_MESSAGES/django.po
new file mode 100644
index 000000000..dec76e273
--- /dev/null
+++ b/troggle/registration/locale/sv/LC_MESSAGES/django.po
@@ -0,0 +1,81 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-03-23 18:59+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Emil Stenström <em@kth.se>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: .\forms.py:38 
+msgid "username"
+msgstr "Användarnamn"
+
+#: .\forms.py:41 
+msgid "email address"
+msgstr "E-postadress"
+
+#: .\forms.py:43 
+msgid "password"
+msgstr "Lösenord"
+
+#: .\forms.py:45 
+msgid "password (again)"
+msgstr "Lösenord (igen)"
+
+#: .\forms.py:54 
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "Användarnamn får bara innehålla bokstäver, siffror och understreck"
+
+#: .\forms.py:59 
+msgid "This username is already taken. Please choose another."
+msgstr "Det användarnamnet är upptaget. Prova ett annat."
+
+#: .\forms.py:71 
+msgid "You must type the same password each time"
+msgstr "Båda lösenord måste vara lika"
+
+#: .\forms.py:100 
+msgid "I have read and agree to the Terms of Service"
+msgstr "Jag har läst och accepterar avtalet"
+
+#: .\forms.py:109 
+msgid "You must agree to the terms to register"
+msgstr "Du måste acceptera avtalet för att registrera dig"
+
+#: .\forms.py:128 
+msgid ""
+"This email address is already in use. Please supply a different email "
+"address."
+msgstr "Den e-postadressen är upptagen, använd an annan adress."
+
+#: .\forms.py:153 
+msgid ""
+"Registration using free email addresses is prohibited. Please supply a "
+"different email address."
+msgstr "Gratis e-postadresser är inte tillåtna, använd en annan adress."
+
+#: .\models.py:188 
+msgid "user"
+msgstr "Användare"
+
+#: .\models.py:189 
+msgid "activation key"
+msgstr "Aktiveringsnyckel"
+
+#: .\models.py:194 
+msgid "registration profile"
+msgstr "Profil"
+
+#: .\models.py:195 
+msgid "registration profiles"
+msgstr "Profiler"
diff --git a/troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo b/troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..ece5cc97b
Binary files /dev/null and b/troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/zh_CN/LC_MESSAGES/django.po b/troggle/registration/locale/zh_CN/LC_MESSAGES/django.po
new file mode 100644
index 000000000..7c609c316
--- /dev/null
+++ b/troggle/registration/locale/zh_CN/LC_MESSAGES/django.po
@@ -0,0 +1,77 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2008-03-20 23:22+0800\n"
+"Last-Translator: hutuworm <hutuworm@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "用户名"
+
+#: forms.py:41
+msgid "email address"
+msgstr "Email 地址"
+
+#: forms.py:43
+msgid "password"
+msgstr "密码"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "密码(重复)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "用户名只能包含字母、数字和下划线"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "该用户名已被占用,请另选一个。"
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "您必须输入两遍同样的密码"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "我已阅读并同意该服务条款"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "您必须同意注册条款"
+
+#: forms.py:124
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "该 Email 地址已有人使用,请提供一个另外的 Email 地址。"
+
+#: forms.py:149
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "禁止使用免费 Email 地址注册,请提供一个另外的 Email 地址。"
+
+#: models.py:188
+msgid "user"
+msgstr "用户"
+
+#: models.py:189
+msgid "activation key"
+msgstr "激活密钥"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "注册信息"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "注册信息"
+
diff --git a/troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo
new file mode 100644
index 000000000..24a353495
Binary files /dev/null and b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo differ
diff --git a/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po
new file mode 100644
index 000000000..7cc090d08
--- /dev/null
+++ b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po
@@ -0,0 +1,77 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-19 19:30-0500\n"
+"PO-Revision-Date: 2008-03-20 23:22+0800\n"
+"Last-Translator: hutuworm <hutuworm@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: forms.py:38
+msgid "username"
+msgstr "用戶名"
+
+#: forms.py:41
+msgid "email address"
+msgstr "Email 地址"
+
+#: forms.py:43
+msgid "password"
+msgstr "密碼"
+
+#: forms.py:45
+msgid "password (again)"
+msgstr "密碼(重復)"
+
+#: forms.py:54
+msgid "Usernames can only contain letters, numbers and underscores"
+msgstr "用戶名只能包含字母、數字和下劃線"
+
+#: forms.py:59
+msgid "This username is already taken. Please choose another."
+msgstr "該用戶名已被佔用,請另選一個。"
+
+#: forms.py:68
+msgid "You must type the same password each time"
+msgstr "您必須輸入兩遍同樣的密碼"
+
+#: forms.py:96
+msgid "I have read and agree to the Terms of Service"
+msgstr "我已閱讀並同意該服務條款"
+
+#: forms.py:105
+msgid "You must agree to the terms to register"
+msgstr "您必須同意注冊條款"
+
+#: forms.py:124
+msgid "This email address is already in use. Please supply a different email address."
+msgstr "該 Email 地址已有人使用,請提供一個另外的 Email 地址。"
+
+#: forms.py:149
+msgid "Registration using free email addresses is prohibited. Please supply a different email address."
+msgstr "禁止使用免費 Email 地址注冊,請提供一個另外的 Email 地址。"
+
+#: models.py:188
+msgid "user"
+msgstr "用戶"
+
+#: models.py:189
+msgid "activation key"
+msgstr "激活密鑰"
+
+#: models.py:194
+msgid "registration profile"
+msgstr "注冊信息"
+
+#: models.py:195
+msgid "registration profiles"
+msgstr "注冊信息"
+
diff --git a/troggle/registration/management/__init__.py b/troggle/registration/management/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/troggle/registration/management/commands/__init__.py b/troggle/registration/management/commands/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/troggle/registration/management/commands/cleanupregistration.py b/troggle/registration/management/commands/cleanupregistration.py
new file mode 100644
index 000000000..abec5aed3
--- /dev/null
+++ b/troggle/registration/management/commands/cleanupregistration.py
@@ -0,0 +1,19 @@
+"""
+A management command which deletes expired accounts (e.g.,
+accounts which signed up but never activated) from the database.
+
+Calls ``RegistrationProfile.objects.delete_expired_users()``, which
+contains the actual logic for determining which accounts are deleted.
+
+"""
+
+from django.core.management.base import NoArgsCommand
+
+from registration.models import RegistrationProfile
+
+
+class Command(NoArgsCommand):
+    help = "Delete expired user registrations from the database"
+
+    def handle_noargs(self, **options):
+        RegistrationProfile.objects.delete_expired_users()
diff --git a/troggle/registration/models.py b/troggle/registration/models.py
new file mode 100644
index 000000000..4a211c179
--- /dev/null
+++ b/troggle/registration/models.py
@@ -0,0 +1,255 @@
+import datetime
+import random
+import re
+import sha
+
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.contrib.sites.models import Site
+from django.db import models
+from django.db import transaction
+from django.template.loader import render_to_string
+from django.utils.translation import ugettext_lazy as _
+
+
+SHA1_RE = re.compile('^[a-f0-9]{40}$')
+
+
+class RegistrationManager(models.Manager):
+    """
+    Custom manager for the ``RegistrationProfile`` model.
+    
+    The methods defined here provide shortcuts for account creation
+    and activation (including generation and emailing of activation
+    keys), and for cleaning out expired inactive accounts.
+    
+    """
+    def activate_user(self, activation_key):
+        """
+        Validate an activation key and activate the corresponding
+        ``User`` if valid.
+        
+        If the key is valid and has not expired, return the ``User``
+        after activating.
+        
+        If the key is not valid or has expired, return ``False``.
+        
+        If the key is valid but the ``User`` is already active,
+        return ``False``.
+        
+        To prevent reactivation of an account which has been
+        deactivated by site administrators, the activation key is
+        reset to the string constant ``RegistrationProfile.ACTIVATED``
+        after successful activation.
+
+        To execute customized logic when a ``User`` is activated,
+        connect a function to the signal
+        ``registration.signals.user_activated``; this signal will be
+        sent (with the ``User`` as the value of the keyword argument
+        ``user``) after a successful activation.
+        
+        """
+        from registration.signals import user_activated
+        
+        # Make sure the key we're trying conforms to the pattern of a
+        # SHA1 hash; if it doesn't, no point trying to look it up in
+        # the database.
+        if SHA1_RE.search(activation_key):
+            try:
+                profile = self.get(activation_key=activation_key)
+            except self.model.DoesNotExist:
+                return False
+            if not profile.activation_key_expired():
+                user = profile.user
+                user.is_active = True
+                user.save()
+                profile.activation_key = self.model.ACTIVATED
+                profile.save()
+                user_activated.send(sender=self.model, user=user)
+                return user
+        return False
+    
+    def create_inactive_user(self, username, password, email,
+                             send_email=True):
+        """
+        Create a new, inactive ``User``, generate a
+        ``RegistrationProfile`` and email its activation key to the
+        ``User``, returning the new ``User``.
+        
+        To disable the email, call with ``send_email=False``.
+
+        The activation email will make use of two templates:
+
+        ``registration/activation_email_subject.txt``
+            This template will be used for the subject line of the
+            email. It receives one context variable, ``site``, which
+            is the currently-active
+            ``django.contrib.sites.models.Site`` instance. Because it
+            is used as the subject line of an email, this template's
+            output **must** be only a single line of text; output
+            longer than one line will be forcibly joined into only a
+            single line.
+
+        ``registration/activation_email.txt``
+            This template will be used for the body of the email. It
+            will receive three context variables: ``activation_key``
+            will be the user's activation key (for use in constructing
+            a URL to activate the account), ``expiration_days`` will
+            be the number of days for which the key will be valid and
+            ``site`` will be the currently-active
+            ``django.contrib.sites.models.Site`` instance.
+
+        To execute customized logic once the new ``User`` has been
+        created, connect a function to the signal
+        ``registration.signals.user_registered``; this signal will be
+        sent (with the new ``User`` as the value of the keyword
+        argument ``user``) after the ``User`` and
+        ``RegistrationProfile`` have been created, and the email (if
+        any) has been sent..
+        
+        """
+        from registration.signals import user_registered
+
+        new_user = User.objects.create_user(username, email, password)
+        new_user.is_active = False
+        new_user.save()
+        
+        registration_profile = self.create_profile(new_user)
+        
+        if send_email:
+            from django.core.mail import send_mail
+            current_site = Site.objects.get_current()
+            
+            subject = render_to_string('registration/activation_email_subject.txt',
+                                       { 'site': current_site })
+            # Email subject *must not* contain newlines
+            subject = ''.join(subject.splitlines())
+            
+            message = render_to_string('registration/activation_email.txt',
+                                       { 'activation_key': registration_profile.activation_key,
+                                         'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
+                                         'site': current_site })
+            
+            send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [new_user.email])
+        user_registered.send(sender=self.model, user=new_user)
+        return new_user
+    create_inactive_user = transaction.commit_on_success(create_inactive_user)
+    
+    def create_profile(self, user):
+        """
+        Create a ``RegistrationProfile`` for a given
+        ``User``, and return the ``RegistrationProfile``.
+        
+        The activation key for the ``RegistrationProfile`` will be a
+        SHA1 hash, generated from a combination of the ``User``'s
+        username and a random salt.
+        
+        """
+        salt = sha.new(str(random.random())).hexdigest()[:5]
+        activation_key = sha.new(salt+user.username).hexdigest()
+        return self.create(user=user,
+                           activation_key=activation_key)
+        
+    def delete_expired_users(self):
+        """
+        Remove expired instances of ``RegistrationProfile`` and their
+        associated ``User``s.
+        
+        Accounts to be deleted are identified by searching for
+        instances of ``RegistrationProfile`` with expired activation
+        keys, and then checking to see if their associated ``User``
+        instances have the field ``is_active`` set to ``False``; any
+        ``User`` who is both inactive and has an expired activation
+        key will be deleted.
+        
+        It is recommended that this method be executed regularly as
+        part of your routine site maintenance; this application
+        provides a custom management command which will call this
+        method, accessible as ``manage.py cleanupregistration``.
+        
+        Regularly clearing out accounts which have never been
+        activated serves two useful purposes:
+        
+        1. It alleviates the ocasional need to reset a
+           ``RegistrationProfile`` and/or re-send an activation email
+           when a user does not receive or does not act upon the
+           initial activation email; since the account will be
+           deleted, the user will be able to simply re-register and
+           receive a new activation key.
+        
+        2. It prevents the possibility of a malicious user registering
+           one or more accounts and never activating them (thus
+           denying the use of those usernames to anyone else); since
+           those accounts will be deleted, the usernames will become
+           available for use again.
+        
+        If you have a troublesome ``User`` and wish to disable their
+        account while keeping it in the database, simply delete the
+        associated ``RegistrationProfile``; an inactive ``User`` which
+        does not have an associated ``RegistrationProfile`` will not
+        be deleted.
+        
+        """
+        for profile in self.all():
+            if profile.activation_key_expired():
+                user = profile.user
+                if not user.is_active:
+                    user.delete()
+
+
+class RegistrationProfile(models.Model):
+    """
+    A simple profile which stores an activation key for use during
+    user account registration.
+    
+    Generally, you will not want to interact directly with instances
+    of this model; the provided manager includes methods
+    for creating and activating new accounts, as well as for cleaning
+    out accounts which have never been activated.
+    
+    While it is possible to use this model as the value of the
+    ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
+    so. This model's sole purpose is to store data temporarily during
+    account registration and activation.
+    
+    """
+    ACTIVATED = u"ALREADY_ACTIVATED"
+    
+    user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
+    activation_key = models.CharField(_('activation key'), max_length=40)
+    
+    objects = RegistrationManager()
+    
+    class Meta:
+        verbose_name = _('registration profile')
+        verbose_name_plural = _('registration profiles')
+    
+    def __unicode__(self):
+        return u"Registration information for %s" % self.user
+    
+    def activation_key_expired(self):
+        """
+        Determine whether this ``RegistrationProfile``'s activation
+        key has expired, returning a boolean -- ``True`` if the key
+        has expired.
+        
+        Key expiration is determined by a two-step process:
+        
+        1. If the user has already activated, the key will have been
+           reset to the string constant ``ACTIVATED``. Re-activating
+           is not permitted, and so this method returns ``True`` in
+           this case.
+
+        2. Otherwise, the date the user signed up is incremented by
+           the number of days specified in the setting
+           ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of
+           days after signup during which a user is allowed to
+           activate their account); if the result is less than or
+           equal to the current date, the key has expired and this
+           method returns ``True``.
+        
+        """
+        expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
+        return self.activation_key == self.ACTIVATED or \
+               (self.user.date_joined + expiration_date <= datetime.datetime.now())
+    activation_key_expired.boolean = True
diff --git a/troggle/registration/signals.py b/troggle/registration/signals.py
new file mode 100644
index 000000000..2a6eed9f3
--- /dev/null
+++ b/troggle/registration/signals.py
@@ -0,0 +1,8 @@
+from django.dispatch import Signal
+
+
+# A new user has registered.
+user_registered = Signal(providing_args=["user"])
+
+# A user has activated his or her account.
+user_activated = Signal(providing_args=["user"])
diff --git a/troggle/registration/tests.py b/troggle/registration/tests.py
new file mode 100644
index 000000000..0f2655392
--- /dev/null
+++ b/troggle/registration/tests.py
@@ -0,0 +1,355 @@
+"""
+Unit tests for django-registration.
+
+These tests assume that you've completed all the prerequisites for
+getting django-registration running in the default setup, to wit:
+
+1. You have ``registration`` in your ``INSTALLED_APPS`` setting.
+
+2. You have created all of the templates mentioned in this
+   application's documentation.
+
+3. You have added the setting ``ACCOUNT_ACTIVATION_DAYS`` to your
+   settings file.
+
+4. You have URL patterns pointing to the registration and activation
+   views, with the names ``registration_register`` and
+   ``registration_activate``, respectively, and a URL pattern named
+   'registration_complete'.
+
+"""
+
+import datetime
+import sha
+
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.core import mail
+from django.core import management
+from django.core.urlresolvers import reverse
+from django.test import TestCase
+
+from registration import forms
+from registration.models import RegistrationProfile
+from registration import signals
+
+
+class RegistrationTestCase(TestCase):
+    """
+    Base class for the test cases; this sets up two users -- one
+    expired, one not -- which are used to exercise various parts of
+    the application.
+    
+    """
+    def setUp(self):
+        self.sample_user = RegistrationProfile.objects.create_inactive_user(username='alice',
+                                                                            password='secret',
+                                                                            email='alice@example.com')
+        self.expired_user = RegistrationProfile.objects.create_inactive_user(username='bob',
+                                                                             password='swordfish',
+                                                                             email='bob@example.com')
+        self.expired_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
+        self.expired_user.save()
+
+
+class RegistrationModelTests(RegistrationTestCase):
+    """
+    Tests for the model-oriented functionality of django-registration,
+    including ``RegistrationProfile`` and its custom manager.
+    
+    """
+    def test_new_user_is_inactive(self):
+        """
+        Test that a newly-created user is inactive.
+        
+        """
+        self.failIf(self.sample_user.is_active)
+
+    def test_registration_profile_created(self):
+        """
+        Test that a ``RegistrationProfile`` is created for a new user.
+        
+        """
+        self.assertEqual(RegistrationProfile.objects.count(), 2)
+
+    def test_activation_email(self):
+        """
+        Test that user signup sends an activation email.
+        
+        """
+        self.assertEqual(len(mail.outbox), 2)
+
+    def test_activation_email_disable(self):
+        """
+        Test that activation email can be disabled.
+        
+        """
+        RegistrationProfile.objects.create_inactive_user(username='noemail',
+                                                         password='foo',
+                                                         email='nobody@example.com',
+                                                         send_email=False)
+        self.assertEqual(len(mail.outbox), 2)
+
+    def test_activation(self):
+        """
+        Test that user activation actually activates the user and
+        properly resets the activation key, and fails for an
+        already-active or expired user, or an invalid key.
+        
+        """
+        # Activating a valid user returns the user.
+        self.failUnlessEqual(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key).pk,
+                             self.sample_user.pk)
+        
+        # The activated user must now be active.
+        self.failUnless(User.objects.get(pk=self.sample_user.pk).is_active)
+        
+        # The activation key must now be reset to the "already activated" constant.
+        self.failUnlessEqual(RegistrationProfile.objects.get(user=self.sample_user).activation_key,
+                             RegistrationProfile.ACTIVATED)
+        
+        # Activating an expired user returns False.
+        self.failIf(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.expired_user).activation_key))
+        
+        # Activating from a key that isn't a SHA1 hash returns False.
+        self.failIf(RegistrationProfile.objects.activate_user('foo'))
+        
+        # Activating from a key that doesn't exist returns False.
+        self.failIf(RegistrationProfile.objects.activate_user(sha.new('foo').hexdigest()))
+
+    def test_account_expiration_condition(self):
+        """
+        Test that ``RegistrationProfile.activation_key_expired()``
+        returns ``True`` for expired users and for active users, and
+        ``False`` otherwise.
+        
+        """
+        # Unexpired user returns False.
+        self.failIf(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired())
+
+        # Expired user returns True.
+        self.failUnless(RegistrationProfile.objects.get(user=self.expired_user).activation_key_expired())
+
+        # Activated user returns True.
+        RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key)
+        self.failUnless(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired())
+
+    def test_expired_user_deletion(self):
+        """
+        Test that
+        ``RegistrationProfile.objects.delete_expired_users()`` deletes
+        only inactive users whose activation window has expired.
+        
+        """
+        RegistrationProfile.objects.delete_expired_users()
+        self.assertEqual(RegistrationProfile.objects.count(), 1)
+
+    def test_management_command(self):
+        """
+        Test that ``manage.py cleanupregistration`` functions
+        correctly.
+        
+        """
+        management.call_command('cleanupregistration')
+        self.assertEqual(RegistrationProfile.objects.count(), 1)
+
+    def test_signals(self):
+        """
+        Test that the ``user_registered`` and ``user_activated``
+        signals are sent, and that they send the ``User`` as an
+        argument.
+        
+        """
+        def receiver(sender, **kwargs):
+            self.assert_('user' in kwargs)
+            self.assertEqual(kwargs['user'].username, u'signal_test')
+            received_signals.append(kwargs.get('signal'))
+
+        received_signals = []
+        expected_signals = [signals.user_registered, signals.user_activated]
+        for signal in expected_signals:
+            signal.connect(receiver)
+
+        RegistrationProfile.objects.create_inactive_user(username='signal_test',
+                                                         password='foo',
+                                                         email='nobody@example.com',
+                                                         send_email=False)
+        RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user__username='signal_test').activation_key)
+
+        self.assertEqual(received_signals, expected_signals)
+
+
+class RegistrationFormTests(RegistrationTestCase):
+    """
+    Tests for the forms and custom validation logic included in
+    django-registration.
+    
+    """
+    def test_registration_form(self):
+        """
+        Test that ``RegistrationForm`` enforces username constraints
+        and matching passwords.
+        
+        """
+        invalid_data_dicts = [
+            # Non-alphanumeric username.
+            {
+            'data':
+            { 'username': 'foo/bar',
+              'email': 'foo@example.com',
+              'password1': 'foo',
+              'password2': 'foo' },
+            'error':
+            ('username', [u"Enter a valid value."])
+            },
+            # Already-existing username.
+            {
+            'data':
+            { 'username': 'alice',
+              'email': 'alice@example.com',
+              'password1': 'secret',
+              'password2': 'secret' },
+            'error':
+            ('username', [u"This username is already taken. Please choose another."])
+            },
+            # Mismatched passwords.
+            {
+            'data':
+            { 'username': 'foo',
+              'email': 'foo@example.com',
+              'password1': 'foo',
+              'password2': 'bar' },
+            'error':
+            ('__all__', [u"You must type the same password each time"])
+            },
+            ]
+
+        for invalid_dict in invalid_data_dicts:
+            form = forms.RegistrationForm(data=invalid_dict['data'])
+            self.failIf(form.is_valid())
+            self.assertEqual(form.errors[invalid_dict['error'][0]], invalid_dict['error'][1])
+
+        form = forms.RegistrationForm(data={ 'username': 'foo',
+                                             'email': 'foo@example.com',
+                                             'password1': 'foo',
+                                             'password2': 'foo' })
+        self.failUnless(form.is_valid())
+
+    def test_registration_form_tos(self):
+        """
+        Test that ``RegistrationFormTermsOfService`` requires
+        agreement to the terms of service.
+        
+        """
+        form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo',
+                                                           'email': 'foo@example.com',
+                                                           'password1': 'foo',
+                                                           'password2': 'foo' })
+        self.failIf(form.is_valid())
+        self.assertEqual(form.errors['tos'], [u"You must agree to the terms to register"])
+        
+        form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo',
+                                                           'email': 'foo@example.com',
+                                                           'password1': 'foo',
+                                                           'password2': 'foo',
+                                                           'tos': 'on' })
+        self.failUnless(form.is_valid())
+
+    def test_registration_form_unique_email(self):
+        """
+        Test that ``RegistrationFormUniqueEmail`` validates uniqueness
+        of email addresses.
+        
+        """
+        form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo',
+                                                        'email': 'alice@example.com',
+                                                        'password1': 'foo',
+                                                        'password2': 'foo' })
+        self.failIf(form.is_valid())
+        self.assertEqual(form.errors['email'], [u"This email address is already in use. Please supply a different email address."])
+
+        form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo',
+                                                        'email': 'foo@example.com',
+                                                        'password1': 'foo',
+                                                        'password2': 'foo' })
+        self.failUnless(form.is_valid())
+
+    def test_registration_form_no_free_email(self):
+        """
+        Test that ``RegistrationFormNoFreeEmail`` disallows
+        registration with free email addresses.
+        
+        """
+        base_data = { 'username': 'foo',
+                      'password1': 'foo',
+                      'password2': 'foo' }
+        for domain in ('aim.com', 'aol.com', 'email.com', 'gmail.com',
+                       'googlemail.com', 'hotmail.com', 'hushmail.com',
+                       'msn.com', 'mail.ru', 'mailinator.com', 'live.com'):
+            invalid_data = base_data.copy()
+            invalid_data['email'] = u"foo@%s" % domain
+            form = forms.RegistrationFormNoFreeEmail(data=invalid_data)
+            self.failIf(form.is_valid())
+            self.assertEqual(form.errors['email'], [u"Registration using free email addresses is prohibited. Please supply a different email address."])
+
+        base_data['email'] = 'foo@example.com'
+        form = forms.RegistrationFormNoFreeEmail(data=base_data)
+        self.failUnless(form.is_valid())
+
+
+class RegistrationViewTests(RegistrationTestCase):
+    """
+    Tests for the views included in django-registration.
+    
+    """
+    def test_registration_view(self):
+        """
+        Test that the registration view rejects invalid submissions,
+        and creates a new user and redirects after a valid submission.
+        
+        """
+        # Invalid data fails.
+        response = self.client.post(reverse('registration_register'),
+                                    data={ 'username': 'alice', # Will fail on username uniqueness.
+                                           'email': 'foo@example.com',
+                                           'password1': 'foo',
+                                           'password2': 'foo' })
+        self.assertEqual(response.status_code, 200)
+        self.failUnless(response.context['form'])
+        self.failUnless(response.context['form'].errors)
+
+        response = self.client.post(reverse('registration_register'),
+                                    data={ 'username': 'foo',
+                                           'email': 'foo@example.com',
+                                           'password1': 'foo',
+                                           'password2': 'foo' })
+        self.assertEqual(response.status_code, 302)
+        self.assertEqual(response['Location'], 'http://testserver%s' % reverse('registration_complete'))
+        self.assertEqual(RegistrationProfile.objects.count(), 3)
+    
+    def test_activation_view(self):
+        """
+        Test that the activation view activates the user from a valid
+        key and fails if the key is invalid or has expired.
+       
+        """
+        # Valid user puts the user account into the context.
+        response = self.client.get(reverse('registration_activate',
+                                           kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.sample_user).activation_key }))
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.context['account'].pk, self.sample_user.pk)
+
+        # Expired user sets the account to False.
+        response = self.client.get(reverse('registration_activate',
+                                           kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.expired_user).activation_key }))
+        self.failIf(response.context['account'])
+
+        # Invalid key gets to the view, but sets account to False.
+        response = self.client.get(reverse('registration_activate',
+                                           kwargs={ 'activation_key': 'foo' }))
+        self.failIf(response.context['account'])
+
+        # Nonexistent key sets the account to False.
+        response = self.client.get(reverse('registration_activate',
+                                           kwargs={ 'activation_key': sha.new('foo').hexdigest() }))
+        self.failIf(response.context['account'])
diff --git a/troggle/registration/urls.py b/troggle/registration/urls.py
new file mode 100644
index 000000000..25cf2b053
--- /dev/null
+++ b/troggle/registration/urls.py
@@ -0,0 +1,72 @@
+"""
+URLConf for Django user registration and authentication.
+
+If the default behavior of the registration views is acceptable to
+you, simply use a line like this in your root URLConf to set up the
+default URLs for registration::
+
+    (r'^accounts/', include('registration.urls')),
+
+This will also automatically set up the views in
+``django.contrib.auth`` at sensible default locations.
+
+But if you'd like to customize the behavior (e.g., by passing extra
+arguments to the various views) or split up the URLs, feel free to set
+up your own URL patterns for these views instead. If you do, it's a
+good idea to use the names ``registration_activate``,
+``registration_complete`` and ``registration_register`` for the
+various steps of the user-signup process.
+
+"""
+
+from django.conf import settings
+from django.conf.urls.defaults import *
+from django.views.generic.simple import direct_to_template
+from django.contrib.auth import views as auth_views
+
+from registration.views import activate
+from registration.views import register
+
+
+urlpatterns = patterns('',
+                       # Activation keys get matched by \w+ instead of the more specific
+                       # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
+                       # that way it can return a sensible "invalid key" message instead of a
+                       # confusing 404.
+                       url(r'^activate/(?P<activation_key>\w+)/$',
+                           activate,
+                           name='registration_activate'),
+                       url(r'^login/$',
+                           auth_views.login,
+                           {'template_name': 'registration/login.html'},
+                           name='auth_login'),
+                       url(r'^logout/$',
+                           auth_views.logout,
+                           {'template_name': 'registration/logout.html'},
+                           name='auth_logout'),
+                       url(r'^password/change/$',
+                           auth_views.password_change,
+                           name='auth_password_change'),
+                       url(r'^password/change/done/$',
+                           auth_views.password_change_done,
+                           name='auth_password_change_done'),
+                       url(r'^password/reset/$',
+                           auth_views.password_reset,
+                           name='auth_password_reset'),
+                       url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
+                           auth_views.password_reset_confirm,
+                           name='auth_password_reset_confirm'),
+                       url(r'^password/reset/complete/$',
+                           auth_views.password_reset_complete,
+                           name='auth_password_reset_complete'),
+                       url(r'^password/reset/done/$',
+                           auth_views.password_reset_done,
+                           name='auth_password_reset_done'),
+                       url(r'^register/$',
+                           register,
+                           name='registration_register'),
+                       url(r'^register/complete/$',
+                           direct_to_template,
+                           {'template': 'registration/registration_complete.html','extra_context':{'settings':settings}},
+                           name='registration_complete'),
+                       )
diff --git a/troggle/registration/views.py b/troggle/registration/views.py
new file mode 100644
index 000000000..aac17c54d
--- /dev/null
+++ b/troggle/registration/views.py
@@ -0,0 +1,153 @@
+"""
+Views which allow users to create and activate accounts.
+
+"""
+
+
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+
+from registration.forms import RegistrationForm
+from registration.models import RegistrationProfile
+
+
+def activate(request, activation_key,
+             template_name='registration/activate.html',
+             extra_context=None):
+    """
+    Activate a ``User``'s account from an activation key, if their key
+    is valid and hasn't expired.
+    
+    By default, use the template ``registration/activate.html``; to
+    change this, pass the name of a template as the keyword argument
+    ``template_name``.
+    
+    **Required arguments**
+    
+    ``activation_key``
+       The activation key to validate and use for activating the
+       ``User``.
+    
+    **Optional arguments**
+       
+    ``extra_context``
+        A dictionary of variables to add to the template context. Any
+        callable object in this dictionary will be called to produce
+        the end result which appears in the context.
+    
+    ``template_name``
+        A custom template to use.
+    
+    **Context:**
+    
+    ``account``
+        The ``User`` object corresponding to the account, if the
+        activation was successful. ``False`` if the activation was not
+        successful.
+    
+    ``expiration_days``
+        The number of days for which activation keys stay valid after
+        registration.
+    
+    Any extra variables supplied in the ``extra_context`` argument
+    (see above).
+    
+    **Template:**
+    
+    registration/activate.html or ``template_name`` keyword argument.
+    
+    """
+    activation_key = activation_key.lower() # Normalize before trying anything with it.
+    account = RegistrationProfile.objects.activate_user(activation_key)
+    if extra_context is None:
+        extra_context = {}
+    context = RequestContext(request)
+    for key, value in extra_context.items():
+        context[key] = callable(value) and value() or value
+    return render_to_response(template_name,
+                              { 'account': account,
+                                'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'settings':settings},
+                              context_instance=context)
+
+
+def register(request, success_url=None,
+             form_class=RegistrationForm,
+             template_name='registration/registration_form.html',
+             extra_context=None):
+    """
+    Allow a new user to register an account.
+    
+    Following successful registration, issue a redirect; by default,
+    this will be whatever URL corresponds to the named URL pattern
+    ``registration_complete``, which will be
+    ``/accounts/register/complete/`` if using the included URLConf. To
+    change this, point that named pattern at another URL, or pass your
+    preferred URL as the keyword argument ``success_url``.
+    
+    By default, ``registration.forms.RegistrationForm`` will be used
+    as the registration form; to change this, pass a different form
+    class as the ``form_class`` keyword argument. The form class you
+    specify must have a method ``save`` which will create and return
+    the new ``User``.
+    
+    By default, use the template
+    ``registration/registration_form.html``; to change this, pass the
+    name of a template as the keyword argument ``template_name``.
+    
+    **Required arguments**
+    
+    None.
+    
+    **Optional arguments**
+    
+    ``form_class``
+        The form class to use for registration.
+    
+    ``extra_context``
+        A dictionary of variables to add to the template context. Any
+        callable object in this dictionary will be called to produce
+        the end result which appears in the context.
+    
+    ``success_url``
+        The URL to redirect to on successful registration.
+    
+    ``template_name``
+        A custom template to use.
+    
+    **Context:**
+    
+    ``form``
+        The registration form.
+    
+    Any extra variables supplied in the ``extra_context`` argument
+    (see above).
+    
+    **Template:**
+    
+    registration/registration_form.html or ``template_name`` keyword
+    argument.
+    
+    """
+    if request.method == 'POST':
+        form = form_class(data=request.POST, files=request.FILES)
+        if form.is_valid():
+            new_user = form.save()
+            # success_url needs to be dynamically generated here; setting a
+            # a default value using reverse() will cause circular-import
+            # problems with the default URLConf for this application, which
+            # imports this file.
+            return HttpResponseRedirect(success_url or reverse('registration_complete'))
+    else:
+        form = form_class()
+    
+    if extra_context is None:
+        extra_context = {}
+    context = RequestContext(request)
+    for key, value in extra_context.items():
+        context[key] = callable(value) and value() or value
+    return render_to_response(template_name,
+                              { 'form': form,'settings':settings },
+                              context_instance=context)
diff --git a/troggle/settings.py b/troggle/settings.py
index 353809d7e..9ad299d62 100644
--- a/troggle/settings.py
+++ b/troggle/settings.py
@@ -46,6 +46,10 @@ TEMPLATE_LOADERS = (
 #   'django.template.loaders.eggs.load_template_source',
 )
 
+TEMPLATE_CONTEXT_PROCESSORS = ( "django.core.context_processors.auth", "troggle.context.settingsContext") 
+
+LOGIN_REDIRECT_URL = '/'
+
 MIDDLEWARE_CLASSES = (
     'django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
@@ -56,6 +60,10 @@ MIDDLEWARE_CLASSES = (
 
 ROOT_URLCONF = 'troggle.urls'
 
+ACCOUNT_ACTIVATION_DAYS=3
+
+AUTH_PROFILE_MODULE = 'expo.person'
+
 INSTALLED_APPS = (
     'django.contrib.admin',
     'django.contrib.auth',
@@ -63,5 +71,7 @@ INSTALLED_APPS = (
     'django.contrib.sessions',
     'django.contrib.sites',
     'django.contrib.redirects',
+    'troggle.registration',
+    'troggle.profiles',
     'troggle.expo'
 )
diff --git a/troggle/templates/base.html b/troggle/templates/base.html
index b1fc47f33..c88ac19d4 100644
--- a/troggle/templates/base.html
+++ b/troggle/templates/base.html
@@ -2,7 +2,7 @@
 <html lang="en">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main2.css" />
+<link rel="stylesheet" type="text/css" href="{{ settings.MEDIA_URL }}css/main3.css" />
 
 <title>{% block title %}THE TITLE{% endblock %}</title>
 
@@ -11,21 +11,34 @@
 </head>
 
 <body>
-<a href="/">
-<div style="float:none">
-  <div id="expoHeader" style="background:#222"> <img src="{{ settings.MEDIA_URL }}loserBanner.jpg" style="position:relative;width:inherit;height:inherit;"/>
+
+<div>
+  <div id="expoHeader"> <img id="frontPageBanner" src="{{ settings.MEDIA_URL }}loserBanner.jpg"/>
     <div id="expoHeaderText">
-      <h1>CUCC Expeditions to Austria: 1976 - 2008</h1>
+      <h1>CUCC Expeditions to Austria: 1976 - </h1>
+      <div id="expoFinalDate">
+        <h1>2009</h1>
+      </div>
     </div>
   </div>
   <hr/>
-  <div id="editLink" style="right:0px; top:0px; text-align: right; position: absolute; top:0; right:0; z-index:1; background:#999"> 
+  <div id="editLink"> 
+  	{% block loginInfo %}
+    	{% if user %}
+	    	You are logged in as {{ user.username }}. 
+            | <a href="{{ settings.URL_ROOT }}/accounts/logout">Log out</a>
+        {% else %}
+        	<a href="{{ settings.URL_ROOT }}/accounts/register">Sign up</a>
+            | <a href="{{ settings.URL_ROOT }}/accounts/login">Log in</a>
+        {% endif %}
+    {% endblock%}
+    | <a href="{{ settings.URL_ROOT }}">Home </a>
  	{% block editLink %}
-    	not editable
+
     {% endblock %}
   </div>
 </div>
-</a>
+
 
 
   {% block nav %}
diff --git a/troggle/templates/personForm.html b/troggle/templates/personForm.html
new file mode 100644
index 000000000..84ee7b79b
--- /dev/null
+++ b/troggle/templates/personForm.html
@@ -0,0 +1,6 @@
+{% extends "base.html" %}
+{% block content %}
+
+{{ form }}
+
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/profiles/create_profile.html b/troggle/templates/profiles/create_profile.html
new file mode 100644
index 000000000..2eed3e480
--- /dev/null
+++ b/troggle/templates/profiles/create_profile.html
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+<form method="post">
+{{ form }}
+<input type="submit" />
+</form>
+
+{% if form.errors %}
+ <p class="errornote">Please correct the errors below</p>
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/profiles/profile_list.html b/troggle/templates/profiles/profile_list.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/troggle/templates/registration/activate.html b/troggle/templates/registration/activate.html
new file mode 100644
index 000000000..f87d519b3
--- /dev/null
+++ b/troggle/templates/registration/activate.html
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}
+registration_form.html | {{ block.super }}
+{% endblock %}
+
+{% block header %}
+<h1>activate.html</h1>
+{% endblock %}
+
+{% block content %}
+You are now activated. 
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/registration/activation_email.txt b/troggle/templates/registration/activation_email.txt
new file mode 100644
index 000000000..3047d8f32
--- /dev/null
+++ b/troggle/templates/registration/activation_email.txt
@@ -0,0 +1,3 @@
+Activate your account in {{ expiration_days }} days...
+{{ URL_ROOT }}{% url registration_activate activation_key %}
+
diff --git a/troggle/templates/registration/activation_email_subject.txt b/troggle/templates/registration/activation_email_subject.txt
new file mode 100644
index 000000000..78ae905dd
--- /dev/null
+++ b/troggle/templates/registration/activation_email_subject.txt
@@ -0,0 +1 @@
+[CUCC Expo] Activation email
\ No newline at end of file
diff --git a/troggle/templates/registration/login.html b/troggle/templates/registration/login.html
new file mode 100644
index 000000000..04b5074e8
--- /dev/null
+++ b/troggle/templates/registration/login.html
@@ -0,0 +1,19 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+{% if form.errors %}
+<p>Your username and password didn't match. Please try again.</p>
+{% endif %}
+
+<form method="post" action=".">
+<table>
+<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
+<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
+</table>
+
+<input type="submit" value="login" />
+<input type="hidden" name="next" value="{{ next }}" />
+</form>
+
+{% endblock %}
diff --git a/troggle/templates/registration/logout.html b/troggle/templates/registration/logout.html
new file mode 100644
index 000000000..9e40c20d3
--- /dev/null
+++ b/troggle/templates/registration/logout.html
@@ -0,0 +1,4 @@
+{% extends "base.html" %}
+{% block content %}
+	You have been logged out.
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/registration/registration_activate.html b/troggle/templates/registration/registration_activate.html
new file mode 100644
index 000000000..cbd540e52
--- /dev/null
+++ b/troggle/templates/registration/registration_activate.html
@@ -0,0 +1,6 @@
+{% extends “base.html” %}
+{% block body %}
+Hello {{ account }}!
+
+Check your email to confirm the activation. There are {{ expiration_days }} days left to do it.
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/registration/registration_complete.html b/troggle/templates/registration/registration_complete.html
new file mode 100644
index 000000000..552fa04e6
--- /dev/null
+++ b/troggle/templates/registration/registration_complete.html
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}
+registration_complete.html | {{ block.super }}
+{% endblock %}
+
+{% block header %}
+<h1>registration_complete.html</h1>
+{% endblock %}
+
+{% block content %}
+Thank you for signing up. An email with the activation code has been sent to your inbox. 
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/templates/registration/registration_form.html b/troggle/templates/registration/registration_form.html
new file mode 100644
index 000000000..17bebf263
--- /dev/null
+++ b/troggle/templates/registration/registration_form.html
@@ -0,0 +1,56 @@
+{% extends "base.html" %}
+
+{% block title %}
+registration_form.html | {{ block.super }}
+{% endblock %}
+
+{% block header %}
+<h1>registration_form.html</h1>
+{% endblock %}
+
+{% block content %}
+<form action="{% url registration_register %}" method="POST">
+<table>
+<tr>
+    <td align="right" valign="top">Username:</td>
+    <td>
+        {{ form.username }} <br/>
+        {% for error in form.username.errors %}
+        <span style="color:red">{{ error }}</span>
+        {% endfor %}
+    </td>
+</tr>
+<tr>
+    <td align="right" valign="top">Email:</td>
+    <td>
+        {{ form.email }} <br/>
+        {% for error in form.email.errors %}
+        <span style="color:red">{{ error }}</span>
+        {% endfor %}
+    </td>
+</tr>
+<tr>
+    <td align="right" valign="top">Password:</td>
+    <td>
+        {{ form.password1 }} <br/>
+        {% for error in form.password1.errors %}
+        <span style="color:red">{{ error }}</span>
+        {% endfor %}
+    </td>
+</tr>
+<tr>
+    <td align="right" valign="top">Password (again):</td>
+    <td>
+        {{ form.password2 }} <br/>
+        {% for error in form.password2.errors %}
+        <span style="color:red">{{ error }}</span>
+        {% endfor %}
+    </td>
+</tr>
+<tr>
+    <td>&nbsp;</td>
+    <td><input type="submit" value="Register" /></td>
+</tr>
+</table>
+</form>
+{% endblock %}
\ No newline at end of file
diff --git a/troggle/urls.py b/troggle/urls.py
index 36c502ebf..8c2810c51 100644
--- a/troggle/urls.py
+++ b/troggle/urls.py
@@ -45,6 +45,11 @@ urlpatterns = patterns('',
     (r'^admin/doc/?', include('django.contrib.admindocs.urls')),
     (r'^admin/(.*)', admin.site.root),
 
+    (r'^accounts/', include('registration.urls')),
+    (r'^profiles/', include('profiles.urls')),
+    
+    (r'^personform/(.*)$', personForm),
+
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
         {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),