← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/kill-entitlements into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/kill-entitlements into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/kill-entitlements/+merge/92888

Kill the never used entitlements interface/model and supporting scripts.

The database table will be dropped in a separate branch.
-- 
https://code.launchpad.net/~stevenk/launchpad/kill-entitlements/+merge/92888
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/kill-entitlements into lp:launchpad.
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql	2012-01-27 09:29:19 +0000
+++ database/sampledata/current-dev.sql	2012-02-14 00:24:21 +0000
@@ -4032,17 +4032,6 @@
 ALTER TABLE emailaddress ENABLE TRIGGER ALL;
 
 
-ALTER TABLE entitlement DISABLE TRIGGER ALL;
-
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (1, 17, 10, 100, 0, '2007-06-11 12:00:00', '2008-06-11 12:00:00', NULL, '2007-06-10 12:00:00', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (2, 17, 20, 200, 0, '2007-06-11 12:00:00', '2008-06-11 12:00:00', NULL, '2007-06-10 12:00:00', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (4, 18, 10, 5, 0, '2007-06-11 12:00:00', '2007-06-11 00:00:00', NULL, '2007-06-11 00:44:19.267601', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (5, 18, 10, 3, 0, '2007-06-11 12:00:00', '2007-06-11 00:00:00', NULL, '2007-06-11 01:02:48.538842', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-
-
-ALTER TABLE entitlement ENABLE TRIGGER ALL;
-
-
 ALTER TABLE faq DISABLE TRIGGER ALL;
 
 INSERT INTO faq (id, title, tags, content, product, distribution, owner, date_created, last_updated_by, date_last_updated, fti) VALUES (1, 'Wireless Networking Documentation', 'wifi', 'Installation instructions for many wireless cards can be found at:

=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql	2012-01-27 09:29:19 +0000
+++ database/sampledata/current.sql	2012-02-14 00:24:21 +0000
@@ -3965,17 +3965,6 @@
 ALTER TABLE emailaddress ENABLE TRIGGER ALL;
 
 
-ALTER TABLE entitlement DISABLE TRIGGER ALL;
-
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (1, 17, 10, 100, 0, '2007-06-11 12:00:00', '2008-06-11 12:00:00', NULL, '2007-06-10 12:00:00', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (2, 17, 20, 200, 0, '2007-06-11 12:00:00', '2008-06-11 12:00:00', NULL, '2007-06-10 12:00:00', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (4, 18, 10, 5, 0, '2007-06-11 12:00:00', '2007-06-11 00:00:00', NULL, '2007-06-11 00:44:19.267601', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-INSERT INTO entitlement (id, person, entitlement_type, quota, amount_used, date_starts, date_expires, registrant, date_created, approved_by, date_approved, state, whiteboard, is_dirty, distribution, product, project) VALUES (5, 18, 10, 3, 0, '2007-06-11 12:00:00', '2007-06-11 00:00:00', NULL, '2007-06-11 01:02:48.538842', NULL, NULL, 30, NULL, true, NULL, NULL, NULL);
-
-
-ALTER TABLE entitlement ENABLE TRIGGER ALL;
-
-
 ALTER TABLE faq DISABLE TRIGGER ALL;
 
 INSERT INTO faq (id, title, tags, content, product, distribution, owner, date_created, last_updated_by, date_last_updated, fti) VALUES (1, 'Wireless Networking Documentation', 'wifi', 'Installation instructions for many wireless cards can be found at:

=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2012-02-13 05:50:16 +0000
+++ lib/lp/registry/configure.zcml	2012-02-14 00:24:21 +0000
@@ -1710,29 +1710,6 @@
             permission="launchpad.Edit"
             interface="lp.registry.interfaces.productrelease.IProductReleaseFileEditRestricted"/>
     </class>
-    <class
-        class="lp.registry.model.entitlement.Entitlement">
-        <require
-            permission="launchpad.View"
-            interface="lp.registry.interfaces.entitlement.IEntitlement"/>
-        <require
-            permission="launchpad.Admin"
-            set_schema="lp.registry.interfaces.entitlement.IEntitlement"/>
-    </class>
-
-    <!-- EntitlementSet -->
-
-    <class
-        class="lp.registry.model.entitlement.EntitlementSet">
-        <allow
-            interface="lp.registry.interfaces.entitlement.IEntitlementSet"/>
-    </class>
-    <securedutility
-        class="lp.registry.model.entitlement.EntitlementSet"
-        provides="lp.registry.interfaces.entitlement.IEntitlementSet">
-        <allow
-            interface="lp.registry.interfaces.entitlement.IEntitlementSet"/>
-    </securedutility>
 
     <!-- SuiteSourcePackage -->
     <class

=== removed file 'lib/lp/registry/doc/entitlement.txt'
--- lib/lp/registry/doc/entitlement.txt	2011-12-30 06:14:56 +0000
+++ lib/lp/registry/doc/entitlement.txt	1970-01-01 00:00:00 +0000
@@ -1,333 +0,0 @@
-= Entitlements =
-
-Entitlements are a means of recording features and privileges
-Launchpad users have been assigned.  The business model for these
-assignments is not important, but it could be through a commercial
-arrangement or through a grant that applies to everyone.
-
-    >>> from datetime import datetime
-    >>> import pytz
-    >>> from lp.services.database.sqlbase import flush_database_updates
-    >>> from lp.testing import login
-    >>> from lp.services.webapp.testing import verifyObject
-    >>> from lp.registry.interfaces.entitlement import (
-    ...     EntitlementQuota,
-    ...     EntitlementState,
-    ...     EntitlementType,
-    ...     IEntitlement,
-    ...     IEntitlementSet,
-    ...     )
-    >>> from lp.registry.interfaces.person import IPersonSet
-
-The logged in user must be an admin in order to change the quota.
-
-    >>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities
-    >>> login("foo.bar@xxxxxxxxxxxxx")
-    >>> foobar = getUtility(ILaunchBag).user
-    >>> lp_admins = getUtility(ILaunchpadCelebrities).admin
-    >>> foobar.inTeam(lp_admins)
-    True
-    >>> entitlements = getUtility(IEntitlementSet)
-    >>> entitlements_in_sample_data = entitlements.count()
-
-Find a team with an entitlement.
-
-    >>> personset = getUtility(IPersonSet)
-    >>> ubuntu_team = personset.getByName('ubuntu-team')
-
-An entitlement grants privilege to use a restricted feature.  The
-'quota' is the number of instances being granted and the
-entitlement_type is the feature being enabled.  The 'person' is the
-person or team being granted the right.  The state for a granted
-entitlement is ACTIVE and the expiration and start dates can be specified.
-
-    >>> UTC = pytz.timezone('UTC')
-    >>> entitlement = getUtility(IEntitlementSet).new(
-    ...     quota=5,
-    ...     entitlement_type=EntitlementType.PRIVATE_BUGS,
-    ...     person=ubuntu_team,
-    ...     state=EntitlementState.ACTIVE,
-    ...     date_expires=datetime(2038, 6, 11, tzinfo=UTC),
-    ...     amount_used=0)
-    >>> verifyObject(IEntitlement, entitlement)
-    True
-
-The person can be accessed and shown to be correct.
-
-    >>> print entitlement.person.name
-    ubuntu-team
-
-If the current date is after the start date (if not None) or before
-the expiration date (if not None) then the in_date_range test will
-pass.
-
-    >>> entitlement.in_date_range
-    True
-
-== Quota checking ==
-
-If the amount used is less than the quota value the exceeded_quota
-test will be false.
-
-    >>> entitlement.quota = 100
-    >>> entitlement.amount_used = 0
-    >>> entitlement.exceeded_quota
-    False
-
-The quota is not exceeded, the date is in range, and the state is
-ACTIVE, so the entitlement is valid.
-
-    >>> entitlement.is_valid
-    True
-
-If the amount used is equal to the quota 'exceeded_quota' should still
-be false and 'is_valid' is still true.
-
-    >>> entitlement.quota = 100
-    >>> entitlement.amount_used = 100
-    >>> entitlement.exceeded_quota
-    False
-    >>> entitlement.is_valid
-    True
-
-However if the amount_used to exceeds the quota, the exceeded quota is
-true and the entitlement is no longer valid.
-
-    >>> entitlement.quota = 100
-    >>> entitlement.amount_used = 101
-    >>> entitlement.exceeded_quota
-    True
-    >>> entitlement.is_valid
-    False
-
-If the quota is UNLIMITED the exceeded quota test is false even when
-using a really large value for amount used.  The entitlement remains
-valid.
-
-We use math.pow here, since __builtin__.pow is overridden by twisted.conch.
-
-    >>> import math
-    >>> entitlement.quota = EntitlementQuota.UNLIMITED
-    >>> entitlement.amount_used = math.pow(10,9)
-    >>> entitlement.exceeded_quota
-    False
-    >>> entitlement.is_valid
-    True
-
-Calling incrementAmountUsed increases the value by one.
-
-    >>> entitlement.quota = 10
-    >>> entitlement.amount_used = 9
-    >>> entitlement.incrementAmountUsed()
-    >>> entitlement.amount_used
-    10
-
-Attempting to increment past the quota will cause an error.
-
-    >>> entitlement.incrementAmountUsed()
-    Traceback (most recent call last):
-      ...
-    EntitlementQuotaExceededError: ...
-
-If the entitlement is invalid for any reason, attempting to increment
-the amount used will cause an error.
-
-    >>> entitlement.state = EntitlementState.INACTIVE
-    >>> entitlement.quota = 50
-    >>> entitlement.incrementAmountUsed()
-    Traceback (most recent call last):
-      ...
-    EntitlementInvalidError: ...
-
-
-== Date range checking ==
-
-The 'in_date_range' attribute can be used to tell whether the
-entitlement is valid with respect to the start date and expires date.
-When the current date is out of range the entitlement is considered
-invalid.
-
-When the entitlement does not have a start date or an expiration date
-then those values are not checked.  If no start date is given the
-expiration date is still used, and vice versa.  If both start date and
-expiration date are None then no date range checking is performed and
-the entitlement is valid with respect to dates.
-
-Remove the start and expiration dates and the date range will be
-valid.
-
-    >>> entitlement.state = EntitlementState.ACTIVE
-    >>> entitlement.date_starts = None
-    >>> entitlement.date_expires = None
-    >>> entitlement.in_date_range
-    True
-    >>> entitlement.is_valid
-    True
-
-    >>> from datetime import datetime, timedelta
-    >>> from pytz import UTC
-    >>> now = datetime.now(UTC)
-    >>> yesterday = now - timedelta(days = 1)
-    >>> tomorrow = now + timedelta(days = 1)
-
-If the start date is in the past and the expiration date is not set
-this condition is considered an open-ended entitlement and we are
-still in its range.
-
-    >>> entitlement.date_starts = yesterday
-    >>> entitlement.in_date_range
-    True
-    >>> entitlement.is_valid
-    True
-
-If the start date is in the future the date is not in range and the
-entitlement is invalid.
-
-    >>> entitlement.date_starts = tomorrow
-    >>> entitlement.in_date_range
-    False
-    >>> entitlement.is_valid
-    False
-
-If the expires date is in the past, we are not in its date range and
-the entitlement is not valid.
-
-    >>> entitlement.date_starts = None
-    >>> entitlement.date_expires = yesterday
-    >>> entitlement.in_date_range
-    False
-    >>> entitlement.is_valid
-    False
-
-If the expiration date is in the future the date range is satisfied
-and the entitlement is valid.
-
-    >>> entitlement.date_expires = tomorrow
-    >>> entitlement.in_date_range
-    True
-    >>> entitlement.is_valid
-    True
-
-If the start date is in the past and the expires date is in the future
-the date range is again satisfied and the entitlement is valid.
-
-    >>> entitlement.date_starts = yesterday
-    >>> entitlement.date_expires = tomorrow
-    >>> entitlement.in_date_range
-    True
-    >>> entitlement.is_valid
-    True
-
-
-== Security ==
-
-Viewing the entitlement's attributes is restricted to the
-entitlement's owner, the entitlement's registrant (or to a member of
-these teams), and to Launchpad administrators.
-
-If logged in as an anonymous user the entitlement values cannot be
-viewed.  A security-wrapped entitlement must be used to exercise the
-security adapters.
-
-    >>> entitlement = ubuntu_team.entitlements[0]
-    >>> entitlement.quota = 50
-    >>> login(ANONYMOUS)
-    >>> entitlement.quota
-    Traceback (most recent call last):
-      ...
-    Unauthorized: (<Entitlement..., 'quota', 'launchpad.View')
-
-
-    >>> entitlement.quota=10
-    Traceback (most recent call last):
-      ...
-    Unauthorized: (<Entitlement..., 'quota', 'launchpad.Admin')
-
-Authenticated Launchpad users who are not the owner or team member are
-similarly restricted.
-
-    >>> login('no-priv@xxxxxxxxxxxxx')
-    >>> entitlement.quota
-    Traceback (most recent call last):
-      ...
-    Unauthorized: (<Entitlement..., 'quota', 'launchpad.View')
-
-
-    >>> entitlement.quota=10
-    Traceback (most recent call last):
-      ...
-    Unauthorized: (<Entitlement..., 'quota', 'launchpad.Admin')
-
-Add the current user to the team and the user can now access
-attributes.  Since ubuntu-team is restricted, an administrator must be
-listed as a reviewer for the membership to go through.
-
-    >>> from lp.registry.interfaces.teammembership import TeamMembershipStatus
-    >>> nopriv = getUtility(ILaunchBag).user
-    >>> mark = personset.getByName('mark')
-    >>> nopriv.join(ubuntu_team)
-
-    # Login as the team's owner in order to be able to change its memberships.
-    >>> login(ubuntu_team.teamowner.preferredemail.email)
-    >>> ubuntu_team.setMembershipData(nopriv, TeamMembershipStatus.APPROVED, mark)
-    >>> login('no-priv@xxxxxxxxxxxxx')
-
-    >>> flush_database_updates()
-    >>> nopriv in ubuntu_team.activemembers
-    True
-    >>> nopriv.inTeam(ubuntu_team)
-    True
-    >>> entitlement.quota
-    50
-
-    >>> entitlement.quota=10
-    Traceback (most recent call last):
-      ...
-    Unauthorized: (<Entitlement..., 'quota', 'launchpad.Admin')
-
-
-= EntitlementSet =
-
-All of the entitlements can be obtained using IEntitlementSet.
-
-    >>> login("foo.bar@xxxxxxxxxxxxx")
-    >>> entitlements = getUtility(IEntitlementSet)
-
-One entitlement was created in the previous examples.
-
-    >>> entitlements.count() - entitlements_in_sample_data
-    1
-
-To look up an entitlement from the set, simply use the 'get' with the id.
-
-    >>> entitlement2 = entitlements.get(entitlement.id)
-    >>> entitlement2.id == entitlement.id
-    True
-
-Get all of the valid entitlements for ubuntu_team.
-
-    >>> valid_list = getUtility(IEntitlementSet).getValidForPerson(ubuntu_team)
-    >>> len(valid_list)
-    1
-
-A new entitlement for the ubuntu_team can be created, increasing the
-number of valid entitlements.
-
-    >>> entitlement = getUtility(IEntitlementSet).new(
-    ...     quota=50,
-    ...     entitlement_type=EntitlementType.PRIVATE_BRANCHES,
-    ...     person=ubuntu_team,
-    ...     state=EntitlementState.ACTIVE,
-    ...     date_expires=datetime(2038, 6, 11, tzinfo=UTC),
-    ...     amount_used=0)
-    >>> valid_list = getUtility(IEntitlementSet).getValidForPerson(ubuntu_team)
-    >>> len(valid_list)
-    2
-
-Setting the original entitlement to INACTIVE will now reduce the
-number of valid entitlements.
-
-    >>> entitlement.state = EntitlementState.INACTIVE
-    >>> valid_list = getUtility(IEntitlementSet).getValidForPerson(ubuntu_team)
-    >>> len(valid_list)
-    1

=== removed file 'lib/lp/registry/interfaces/entitlement.py'
--- lib/lp/registry/interfaces/entitlement.py	2011-12-24 16:54:44 +0000
+++ lib/lp/registry/interfaces/entitlement.py	1970-01-01 00:00:00 +0000
@@ -1,242 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=E0211,E0213
-
-"""Entitlement interfaces."""
-
-__metaclass__ = type
-
-__all__ = [
-    'EntitlementInvalidError',
-    'EntitlementQuota',
-    'EntitlementQuotaExceededError',
-    'EntitlementState',
-    'EntitlementType',
-    'IEntitlement',
-    'IEntitlementSet',
-    ]
-
-from lazr.enum import (
-    DBEnumeratedType,
-    DBItem,
-    )
-from zope.interface import (
-    Attribute,
-    Interface,
-    )
-from zope.schema import (
-    Bool,
-    Choice,
-    Datetime,
-    Int,
-    )
-
-from lp import _
-from lp.services.fields import Whiteboard
-
-
-class EntitlementQuotaExceededError(Exception):
-    """The quota has been exceeded for the entitlement."""
-
-
-class EntitlementInvalidError(Exception):
-    """The entitlement is not valid."""
-
-
-class EntitlementType(DBEnumeratedType):
-    """The set of features supported via entitlements.
-
-    The listed features may be enabled by the granting of an entitlement.
-    """
-
-    PRIVATE_BRANCHES = DBItem(10, """
-        Private Branches
-
-        The ability to create branches which are only visible to the team.
-        """)
-
-    PRIVATE_BUGS = DBItem(20, """
-        Private Bugs
-
-        The ability to create private bugs which are only visible to the team.
-        """)
-
-    PRIVATE_TEAMS = DBItem(30, """
-        Private Teams
-
-        The ability to create private teams which are only visible to parent
-        teams.
-        """)
-
-
-class EntitlementState(DBEnumeratedType):
-    """States for an entitlement.
-
-    The entitlement may start life as a REQUEST that is then granted and
-    made ACTIVE.  At some point the entitlement may be revoked by marking
-    as INACTIVE.
-    """
-
-    REQUESTED = DBItem(10, """
-        Entitlement has been requested.
-
-        The entitlement is inactive in this state.
-        """)
-
-    ACTIVE = DBItem(20, """
-        The entitlement is active.
-
-        The entitlement is approved in Launchpad or was imported in the
-        active state.
-        """)
-
-    INACTIVE = DBItem(30, """
-        The entitlement is inactive.
-
-        The entitlement has be deactivated.
-        """)
-
-
-class IEntitlement(Interface):
-    """An entitlement the right to use a specific feature in Launchpad.
-
-    Entitlements can be granted in an unlimited quantity or with a given
-    quota.  They have a start date and optionally an expiration date.  An
-    entitlement is invalid if it is not active, the quota is exceeded, or if
-    it is expired.
-    """
-
-    id = Int(
-        title=_("Entitlement id"),
-        required=True,
-        readonly=True)
-    person = Choice(
-        title=_('Person'),
-        required=True,
-        readonly=True,
-        vocabulary='ValidPersonOrTeam',
-        description=_("Person or team to whom the entitlements is assigned."))
-    date_created = Datetime(
-        title=_("Date Created"),
-        description=_("The date on which this entitlement was created."),
-        required=True,
-        readonly=True)
-    date_starts = Datetime(
-        title=_("Date Starts"),
-        description=_("The date on which this entitlement starts."),
-        readonly=False)
-    date_expires = Datetime(
-        title=_("Date Expires"),
-        description=_("The date on which this entitlement expires."),
-        readonly=False)
-    entitlement_type = Choice(
-        title=_("Type of entitlement."),
-        required=True,
-        vocabulary='EntitlementType',
-        description=_("Type of feature for this entitlement."),
-        readonly=True)
-    quota = Int(
-        title=_("Allocated quota."),
-        required=True,
-        description=_(
-            "A quota is the number of a feature allowed by this entitlement, "
-            "for instance 50 private bugs."))
-    amount_used = Int(
-        title=_("Amount used."),
-        description=_(
-            "The amount used is the number of instances of a feature "
-            "the person has used so far."))
-    registrant = Choice(
-        title=_('Registrant'),
-        vocabulary='ValidPersonOrTeam',
-        description=_(
-            "Person who registered the entitlement.  "
-            "May be None if created automatically."),
-        readonly=True)
-    approved_by = Choice(
-        title=_('Approved By'),
-        vocabulary='ValidPersonOrTeam',
-        description=_(
-            "Person who approved the entitlement.  "
-            "May be None if created automatically."),
-        readonly=True)
-    state = Choice(
-        title=_("State"),
-        required=True,
-        vocabulary='EntitlementState',
-        description = _("Current state of the entitlement."))
-
-    whiteboard = Whiteboard(title=_('Whiteboard'), required=False,
-        description=_('Notes on the current status of the entitlement.'))
-
-    is_dirty = Bool(
-        title=_("Dirty?"),
-        description=_(
-            "Is the entitlement 'dirty', i.e. has been written since the "
-            "most recent update to an external system?"))
-
-    is_valid = Attribute(
-        "Is this entitlement valid?")
-
-    exceeded_quota = Attribute(
-        "If the quota is not unlimited, is it exceeded?")
-
-    in_date_range = Attribute(
-        "Has the start date passed but not the expiration date?")
-
-    def incrementAmountUsed():
-        """Add one to the amount used."""
-
-
-class IEntitlementSet(Interface):
-    """Interface representing a set of Entitlements."""
-
-    def __getitem__(entitlement_id):
-        """Return the entitlement with the given id.
-
-        Raise NotFoundError if there is no such entitlement.
-        """
-
-    def __iter__():
-        """Return an iterator that will go through all entitlements."""
-
-    def count():
-        """Return the number of entitlements in the database."""
-
-    def get(entitlement_id, default=None):
-        """Return the entitlement with the given id.
-
-        Return the default value if there is no such entitlement.
-        """
-
-    def getForPerson(person):
-        """Return the entitlements for the person or team.
-
-        Get all entitlements for a person.
-        """
-
-    def getValidForPerson(person):
-        """Return a list of valid entitlements for the person or team.
-
-        Get all valid entitlements for a person.  None is returned if no valid
-        entitlements are found.
-        """
-
-    def getDirty():
-        """Return the entitlements that have the dirty bit set.
-
-        Get all entitlements that are marked as dirty.
-        """
-
-    def new(person, quota, entitlement_type, state,
-            is_dirty=True, date_created=None, date_expires=None,
-            date_starts=None, amount_used=None, registrant=None,
-            approved_by=None):
-        """Create a new entitlement."""
-
-
-class EntitlementQuota:
-    """This class stores constants for entitlements quotas."""
-
-    UNLIMITED = 0

=== modified file 'lib/lp/registry/interfaces/person.py'
--- lib/lp/registry/interfaces/person.py	2012-02-13 23:02:42 +0000
+++ lib/lp/registry/interfaces/person.py	2012-02-14 00:24:21 +0000
@@ -1022,8 +1022,6 @@
             # Really IArchive, see archive.py
             value_type=Reference(schema=Interface)))
 
-    entitlements = Attribute("List of Entitlements for this person or team.")
-
     structural_subscriptions = Attribute(
         "The structural subscriptions for this person.")
 

=== removed file 'lib/lp/registry/model/entitlement.py'
--- lib/lp/registry/model/entitlement.py	2011-12-30 06:14:56 +0000
+++ lib/lp/registry/model/entitlement.py	1970-01-01 00:00:00 +0000
@@ -1,189 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=E0611,W0212
-
-__metaclass__ = type
-__all__ = ['Entitlement', 'EntitlementSet']
-
-from datetime import datetime
-
-import pytz
-from sqlobject import (
-    BoolCol,
-    ForeignKey,
-    IntCol,
-    SQLObjectNotFound,
-    StringCol,
-    )
-from zope.interface import implements
-
-from lp.app.errors import NotFoundError
-from lp.registry.interfaces.entitlement import (
-    EntitlementInvalidError,
-    EntitlementQuota,
-    EntitlementQuotaExceededError,
-    EntitlementState,
-    EntitlementType,
-    IEntitlement,
-    IEntitlementSet,
-    )
-from lp.services.database.constants import DEFAULT
-from lp.services.database.datetimecol import UtcDateTimeCol
-from lp.services.database.enumcol import EnumCol
-from lp.services.database.sqlbase import SQLBase
-
-
-class Entitlement(SQLBase):
-    """A table recording the entitlements for a person or team."""
-
-    implements(IEntitlement)
-    _table = 'Entitlement'
-    _defaultOrder = ['person', '-date_expires']
-
-    person = ForeignKey(
-        dbName='person', foreignKey='Person',
-        default=None, notNull=True)
-    date_created = UtcDateTimeCol(notNull=True, default=DEFAULT)
-    date_starts = UtcDateTimeCol(notNull=False, default=None)
-    date_expires = UtcDateTimeCol(notNull=False, default=None)
-
-    entitlement_type = EnumCol(
-        dbName='entitlement_type',
-        notNull=True,
-        enum=EntitlementType,
-        default=EntitlementType.PRIVATE_BUGS)
-    quota = IntCol(notNull=True)
-    amount_used = IntCol(notNull=True, default=0)
-    registrant = ForeignKey(
-        dbName='registrant', foreignKey='Person',
-        default=None, notNull=False)
-    approved_by = ForeignKey(
-        dbName='approved_by', foreignKey='Person',
-        default=None, notNull=False)
-    state = EnumCol(
-        dbName='state',
-        notNull=True,
-        enum=EntitlementState,
-        default=EntitlementState.INACTIVE)
-    whiteboard = StringCol(notNull=False, default=None)
-    is_dirty = BoolCol(dbName="is_dirty", notNull=True, default=True)
-
-    @property
-    def exceeded_quota(self):
-        """See IEntitlement."""
-        if self.quota == EntitlementQuota.UNLIMITED:
-            return False
-        else:
-            return self.amount_used > self.quota
-
-    def _isExpired(self, now=None):
-        if now is None:
-            now = datetime.now(pytz.timezone('UTC'))
-        if self.date_expires is None:
-            return False
-        else:
-            return now > self.date_expires
-
-    def _hasNotYetStarted(self, now=None):
-        if now is None:
-            now = datetime.now(pytz.timezone('UTC'))
-        if self.date_starts is None:
-            return False
-        else:
-            return now < self.date_starts
-
-    @property
-    def in_date_range(self):
-        """See IEntitlement."""
-        now = datetime.now(pytz.timezone('UTC'))
-        too_late = self._isExpired(now)
-        too_early = self._hasNotYetStarted(now)
-        just_right = not (too_late or too_early)
-        return just_right
-
-    @property
-    def is_valid(self):
-        """See IEntitlement."""
-        if self.state != EntitlementState.ACTIVE:
-            return False
-        else:
-            return self.in_date_range and not self.exceeded_quota
-
-    def incrementAmountUsed(self):
-        """See IEntitlement."""
-        if not self.is_valid:
-            raise EntitlementInvalidError(
-                "This entitlement is invalid and cannot be used.")
-
-        self.amount_used += 1
-
-        if self.exceeded_quota:
-            self.amount_used -= 1
-            raise EntitlementQuotaExceededError(
-                "The quota for this entitlement has been exceeded.")
-
-
-class EntitlementSet:
-    """The set of all entitlements."""
-
-    implements(IEntitlementSet)
-
-    def __getitem__(self, entitlement_id):
-        """See `IEntitlementSet`."""
-        entitlement = self.get(entitlement_id)
-        if entitlement is None:
-            raise NotFoundError(entitlement_id)
-        return entitlement
-
-    def __iter__(self):
-        """See `IEntitlementSet`."""
-        return iter(Entitlement.select())
-
-    def count(self):
-        """See `IEntitlementSet`."""
-        return Entitlement.select().count()
-
-    def get(self, entitlement_id, default=None):
-        """See `IEntitlementSet`."""
-        try:
-            return Entitlement.get(entitlement_id)
-        except SQLObjectNotFound:
-            return default
-
-    def getForPerson(self, person):
-        """See `IEntitlementSet`."""
-        return Entitlement.selectBy(person=person)
-
-    def getValidForPerson(self, person):
-        """See `IEntitlementSet`."""
-        entitlements = self.getForPerson(person)
-        return [entitlement for entitlement in entitlements
-                if entitlement.is_valid]
-
-    def getDirty(self):
-        """See `IEntitlementSet`."""
-        return Entitlement.selectBy(is_dirty=True)
-
-    def new(self, person, quota, entitlement_type,
-            state, is_dirty=True, date_created=None, date_starts=None,
-            date_expires=None, amount_used=0, registrant=None,
-            approved_by=None, whiteboard=None):
-        """See `IEntitlementSet`."""
-
-        if date_created is None:
-            date_created = datetime.now(pytz.timezone('UTC'))
-
-        return Entitlement(
-            person=person,
-            quota=quota,
-            entitlement_type=entitlement_type,
-            state=state,
-            is_dirty=is_dirty,
-            date_created=date_created,
-            date_starts=date_starts,
-            date_expires=date_expires,
-            amount_used=amount_used,
-            registrant=registrant,
-            approved_by=approved_by,
-            whiteboard=whiteboard)

=== modified file 'lib/lp/registry/model/person.py'
--- lib/lp/registry/model/person.py	2012-02-13 23:02:42 +0000
+++ lib/lp/registry/model/person.py	2012-02-14 00:24:21 +0000
@@ -595,7 +595,6 @@
     _ircnicknames = SQLMultipleJoin('IrcID', joinColumn='person')
     jabberids = SQLMultipleJoin('JabberID', joinColumn='person')
 
-    entitlements = SQLMultipleJoin('Entitlement', joinColumn='person')
     visibility = EnumCol(
         enum=PersonVisibility,
         default=PersonVisibility.PUBLIC,

=== removed file 'lib/lp/registry/scripts/entitlement.py'
--- lib/lp/registry/scripts/entitlement.py	2011-12-19 23:38:16 +0000
+++ lib/lp/registry/scripts/entitlement.py	1970-01-01 00:00:00 +0000
@@ -1,330 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Import entitlements from Salesforce.
-
-Provide a class that allows the writing and reading of entitlement exchange
-files and a class to create and update entitlements in Launchpad.
-"""
-
-__metaclass__ = type
-__all__ = [
-    'EntitlementExchange',
-    'EntitlementImporter',
-    'InvalidFormat',
-    'NoSuchEntitlement',
-    'UnsupportedVersion',
-    ]
-
-import cStringIO
-import csv
-import datetime
-import re
-import time
-
-import pytz
-from zope.component import getUtility
-
-from lp.app.errors import NotFoundError
-from lp.registry.interfaces.entitlement import (
-    EntitlementState,
-    EntitlementType,
-    IEntitlementSet,
-    )
-from lp.registry.interfaces.person import IPersonSet
-from lp.services.unicode_csv import (
-    UnicodeDictReader,
-    UnicodeDictWriter,
-    )
-
-
-COMMENT = '#'
-COMMA = ','
-
-
-class NoSuchEntitlement(Exception):
-    """Used if a non-existent entitlement is specified."""
-
-
-class UnsupportedVersion(Exception):
-    """Used if the version is not supported."""
-
-
-class InvalidFormat(Exception):
-    """Used if the file format is not as expected."""
-
-
-class RequiredValueMissing(Exception):
-    """Used if a required value was not provided."""
-
-
-class EntitlementExchange:
-    """Define the exchange format for entitlement data.
-
-    Writers of entitlement data should use the 'writerFactory' method to
-    obtain a writer object.  Readers should use the 'readerFactory'.  They
-    return a UnicodeDictWriter and UnicodeDictReader respectively.
-
-    Any changes to the list of fieldnames or their order will require an
-    increment in the version value.
-    """
-
-    file_header = "%s Entitlement exchange format version" % COMMENT
-    version = 1
-    version_re = re.compile(
-        "^%s (\d+)" % file_header)
-
-    fieldnames = [
-        'id', 'ext_id', 'person_name', 'entitlement_type', 'quota',
-        'amount_used', 'date_starts', 'date_expires', 'date_created',
-        'registrant_name', 'approved_by_name', 'state', 'whiteboard',
-        ]
-
-    @staticmethod
-    def _preprocessData(in_file):
-        """Verify the version and remove comments."""
-        version_line = in_file.readline()
-        match = EntitlementExchange.version_re.search(version_line)
-        if not match:
-            raise InvalidFormat(
-                "The first line does not have valid version information.")
-        read_version = int(match.group(1))
-        if EntitlementExchange.version != read_version:
-            raise UnsupportedVersion(
-                "Version %d of the file format is not supported." %
-                read_version)
-        lines= [line for line in in_file.readlines()
-                if not line.lstrip().startswith(COMMENT)]
-        return "".join(lines)
-
-    @staticmethod
-    def readerFactory(in_file):
-        """Return a properly provisioned reader.
-
-        Assumes data in the file is UTF-8 encoded.
-        """
-
-        filedata = EntitlementExchange._preprocessData(in_file)
-        return UnicodeDictReader(cStringIO.StringIO(filedata),
-                                 EntitlementExchange.fieldnames,
-                                 skipinitialspace=True,
-                                 quoting=csv.QUOTE_ALL)
-
-    @staticmethod
-    def writerFactory(filedescriptor):
-        """Return a properly provisioned writer.
-
-        Data in the file will be UTF-8 encoded.
-        """
-
-        filedescriptor.write(
-            "%s %d\n" % (EntitlementExchange.file_header,
-                         EntitlementExchange.version))
-        filedescriptor.write(
-            "%s %s\n" % (COMMENT,
-                        COMMA.join(EntitlementExchange.fieldnames)))
-        writer = UnicodeDictWriter(filedescriptor,
-                                   EntitlementExchange.fieldnames,
-                                   skipinitialspace=True,
-                                   quoting=csv.QUOTE_ALL)
-        return writer
-
-
-class EntitlementImporter:
-    """Class for writing and updating entitlement data.
-
-    Methods create_entitlements and update_entitlements are called with a list
-    of dictionaries representing entitlement data.
-    """
-    def __init__(self, logger):
-        self.logger = logger
-
-    def _replacePersonName(self, entitlement, old_key, new_key,
-                           row_no, required=False):
-        """Replace a person's name with a Person object in the entitlement.
-
-        Raise RequiredValueMissing if the old_key is not found in the
-        entitlement dictionary and required is True.
-        Raise NotFoundError if no matching person can be found.
-        """
-        person_name = entitlement.get(old_key, '')
-        del entitlement[old_key]
-        if person_name == '':
-            if required:
-                raise RequiredValueMissing(
-                    "'person_name' not supplied in row %d." % row_no)
-            else:
-                return entitlement
-        person = getUtility(IPersonSet).getByName(person_name)
-        if person is None:
-            self.logger.error(
-                "[E%d] Person '%s' is not found." % (
-                row_no, person_name))
-            raise NotFoundError(
-                "Person '%s' not supplied in row %d." % (
-                person_name, row_no))
-        entitlement[new_key] = person
-        return entitlement
-
-    def _normalizeEntitlement(
-        self, entitlement, row_no, person_required=True):
-        """Normalize a dictionary representing an entitlement.
-
-        Convert names of people and teams to database objects and
-        convert string representations of numerics to the correct type.
-        Remove any keys in the dictionary that do not correspond to attributes
-        on an Entitlement.
-        """
-        entitlement = self._replacePersonName(
-            entitlement, 'person_name', 'person', row_no, person_required)
-        entitlement = self._replacePersonName(
-            entitlement, 'registrant_name', 'registrant', row_no)
-        entitlement = self._replacePersonName(
-            entitlement, 'approved_by_name', 'approved_by', row_no)
-
-        # Remove the 'ext_id' since it is not part of the Launchpad data.
-        del entitlement['ext_id']
-
-        # Convert numeric data from string to int.
-        for field in ['id', 'quota', 'entitlement_type', 'state', 'amount_used']:
-            if entitlement[field]:
-                entitlement[field] = int(entitlement[field])
-
-        # Convert strings to dates.
-        for field in ['date_starts', 'date_expires', 'date_created']:
-            if entitlement[field]:
-                date_string = entitlement[field]
-                if len(date_string) == len('YYYY-mm-dd'):
-                    year, month, day, hour, minute, second = time.strptime(
-                        date_string, '%Y-%m-%d')[:6]
-                elif len(date_string) == len('YYYY-mm-dd HH:MM:SS'):
-                    year, month, day, hour, minute, second = time.strptime(
-                        date_string, '%Y-%m-%d %H:%M:%S')[:6]
-                else:
-                    raise AssertionError(
-                        'Unknown date format: %s' % date_string)
-                entitlement[field] = datetime.datetime(
-                    year, month, day, hour, minute, second,
-                    tzinfo=pytz.timezone('UTC'))
-
-        # Convert the entitlement_type and state to the corresponding
-        # database objects.
-        if entitlement['entitlement_type']:
-            entitlement_type = entitlement['entitlement_type']
-            entitlement['entitlement_type'] = (
-                EntitlementType.items.mapping[entitlement_type])
-
-        if entitlement['state']:
-            state = entitlement['state']
-            entitlement['state'] = (
-                EntitlementState.items.mapping[state])
-
-        # Remove the entries from the dictionary that only have placeholder
-        # data.
-        for key, value in entitlement.items():
-            if value == '':
-                del entitlement[key]
-        return entitlement
-
-    def _checkRequired(self, entitlement, required, row_no):
-        """Check to see that all required keys are in the entitlement."""
-        for key in required:
-            val = entitlement.get(key, '')
-            # Test for None or ''.  No boolean variable are expected.
-            if val == '':
-                self.logger.error(
-                    "[E%d] A required key is missing: %s." % (row_no, key))
-                return False
-        return True
-
-    def createEntitlements(self, entitlements):
-        """Create a new entitlement for each in the list.
-
-        Return a list of sparsely populated dictionaries suitable for writing
-        as a return CSV file.
-        """
-
-        required = ['ext_id', 'person_name', 'quota', 'entitlement_type',
-                    'state']
-        entitlement_set = getUtility(IEntitlementSet)
-        new_entitlements = []
-        for row_no, entitlement in enumerate(entitlements):
-            if self._checkRequired(entitlement, required, row_no) is False:
-                continue
-            ext_id = entitlement.get('ext_id')
-            try:
-                normalized_entitlement = self._normalizeEntitlement(
-                    entitlement, row_no)
-            except NotFoundError:
-                continue
-            except RequiredValueMissing:
-                continue
-
-            new_entitlement = entitlement_set.new(**normalized_entitlement)
-
-            if new_entitlement is not None:
-                # Add a dictionary with id and ext_id to the list of
-                # new entitlements.
-                new_entitlements.append(dict(id=str(new_entitlement.id),
-                                             ext_id=ext_id))
-        return new_entitlements
-
-    def updateEntitlements(self, entitlements):
-        """Update an existing entitlement.
-
-        The entitlement must already exist.  A list of dictionaries with the
-        ids of the entitlments that were modified is returned.
-        """
-
-        modified = []
-        required = ['id']
-        for row_no, upd_entitlement in enumerate(entitlements):
-            if not self._checkRequired(upd_entitlement, required, row_no):
-                continue
-            # The ext_id must be cached before the data is normalized.
-            ext_id = upd_entitlement.get('ext_id')
-
-            try:
-                norm_entitlement = self._normalizeEntitlement(
-                    upd_entitlement, row_no, person_required=False)
-            except NotFoundError:
-                continue
-            except RequiredValueMissing:
-                continue
-
-            lp_id = norm_entitlement.get('id')
-            entitlement_set = getUtility(IEntitlementSet)
-
-            existing = entitlement_set.get(lp_id)
-            if existing is None:
-                self.logger.error(
-                    "[E%d] Invalid entitlement id: %d" % (row_no,
-                                                          lp_id))
-                continue
-
-            succeeded = True
-            for (key, val) in norm_entitlement.items():
-                if key == 'id':
-                    pass
-                elif key == 'person':
-                    self.logger.info(
-                        "[E%d] You may not change the person for the "
-                        "entitlement." % (row_no))
-                    succeeded = False
-                    break
-                elif key == 'whiteboard':
-                    # Append the whiteboard value rather than replacing it.
-                    existing.whiteboard = "%s\n%s" % (existing.whiteboard,
-                                                      val)
-                elif key in ['entitlement_type', 'quota', 'amount_used',
-                             'date_starts', 'date_expires', 'date_created',
-                             'registrant', 'approved_by', 'state']:
-                    setattr(existing, key, val)
-                else:
-                    self.logger.error(
-                        "[E%d] Unrecognized key: %s." % (row_no, key))
-                    succeeded = False
-                    break
-            if succeeded:
-                modified.append(dict(id=str(lp_id)))
-        return modified

=== removed file 'lib/lp/registry/tests/test_entitlementimport.py'
--- lib/lp/registry/tests/test_entitlementimport.py	2012-01-01 02:58:52 +0000
+++ lib/lp/registry/tests/test_entitlementimport.py	1970-01-01 00:00:00 +0000
@@ -1,184 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test EntitlementExchange and EntitlementImporter."""
-
-__metaclass__ = type
-
-from cStringIO import StringIO
-import logging
-import unittest
-
-from zope.testing.loghandler import Handler
-
-from lp.registry.scripts.entitlement import (
-    EntitlementExchange,
-    EntitlementImporter,
-    InvalidFormat,
-    UnsupportedVersion,
-    )
-from lp.testing.layers import LaunchpadZopelessLayer
-
-
-class EntitlementExchangeTestCase(unittest.TestCase):
-    """Test EntitlementExchange methods."""
-    layer = LaunchpadZopelessLayer
-
-    def test_preprocessData(self):
-        """The preprocessor verifies the header and removes comments."""
-        # Wrong header
-        data = ("# bad format data\n"
-                "more data")
-        in_file = StringIO(data)
-        self.assertRaises(
-            InvalidFormat, EntitlementExchange._preprocessData, in_file)
-
-        # Invalid version
-        data = ("# Entitlement exchange format version 0\n"
-                "more data")
-        in_file = StringIO(data)
-        self.assertRaises(
-            UnsupportedVersion, EntitlementExchange._preprocessData, in_file)
-
-        # Only one line should remain after processing
-        data = ("# Entitlement exchange format version 1\n"
-                "# comment line\n"
-                "    # another comment\n"
-                "'name', 'date' #valid line")
-        in_file = StringIO(data)
-        processed = EntitlementExchange._preprocessData(in_file)
-        self.assertEqual(len(processed.split('\n')), 1)
-
-class EntitlementImporterTestCase(unittest.TestCase):
-    """Test EntitlementImport methods."""
-    layer = LaunchpadZopelessLayer
-
-    def setUp(self):
-        """Setup the test environment and retrieve useful instances."""
-        self.log = logging.getLogger("test_entitlement")
-        self.log.setLevel(logging.INFO)
-        self.handler = Handler(self)
-        self.handler.add(self.log.name)
-
-    def tearDown(self):
-        """Teardown the test environment."""
-        self.layer.txn.commit()
-        self.handler.close()
-
-    def _getImporterAndReader(self, data):
-        in_file = StringIO(data)
-        importer = EntitlementImporter(self.log)
-        return importer, EntitlementExchange.readerFactory(in_file)
-
-    def _testCreate(self, data):
-        importer, reader = self._getImporterAndReader(data)
-        return importer.createEntitlements(reader)
-
-    def _testUpdate(self, data):
-        importer, reader = self._getImporterAndReader(data)
-        return importer.updateEntitlements(reader)
-
-    def test_manipulateEntitlement(self):
-        """Test creating and updating entitlements."""
-
-    def test_wrongVersion(self):
-        """Wrong version."""
-        data = r"""# Entitlement exchange format version 0"""
-        in_file = StringIO(data)
-        importer = EntitlementImporter(self.log)
-        self.assertRaises(UnsupportedVersion,
-                          EntitlementExchange.readerFactory,
-                          in_file)
-
-    def test_successfulInsert(self):
-        """Successfully insert an entitlement."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, lifeless, 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.assertEqual(len(results), 1)
-
-    def test_insertUsingNonExistentPerson(self):
-        """Attempt to insert using a non-existent person."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, persona_non_grata, 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] Person 'persona_non_grata' "
-            "is not found.", level=logging.ERROR)
-
-    def test_omitQuota(self):
-        """Omit the quota and get an error."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, lifeless, 10, ,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] A required key is missing: quota.",
-            level=logging.ERROR)
-
-    def test_omitPerson(self):
-        """Omit the person and get an error."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, , 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] A required key is missing: person_name.",
-            level=logging.ERROR)
-
-    def test_omitExtId(self):
-        """Omit the ext_id and get an error."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",, lifeless, 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] A required key is missing: ext_id.",
-            level=logging.ERROR)
-
-    def test_omitEntitlementType(self):
-        """Omit the entitlement_type and get an error."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, lifeless, , 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] A required key is missing: entitlement_type.",
-            level=logging.ERROR)
-
-    def test_omitState(self):
-        """Omit the state and get an error."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, lifeless, 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, ,")
-        results = self._testCreate(data)
-        self.handler.assertLogsMessage(
-            "[E0] A required key is missing: state.",
-            level=logging.ERROR)
-
-    def test_updateWithInvalidId(self):
-        """Update using an invalid entitlement id."""
-        data = ("# Entitlement exchange format version 1\n"
-                "9999,A-100,kiko, ,1500, , , , , , , , ")
-        results = self._testUpdate(data)
-        self.handler.assertLogsMessage(
-            "[E0] Invalid entitlement id: 9999",
-            level=logging.ERROR)
-
-    def test_updateChangingPerson(self):
-        """Changing the person, which isn't allowed."""
-        data = ("# Entitlement exchange format version 1\n"
-                ",A-100, lifeless, 10, 100,  0, 2007-06-14, , , "
-                "keybuk, keybuk, 20,")
-        results = self._testCreate(data)
-        self.assertEqual(len(results), 1)
-        valid_id = results[0].get('id')
-        data = ("# Entitlement exchange format version 1\n"
-                " %s, A-100, kiko, , 1500, , , , , , , , " %
-                valid_id)
-        results = self._testUpdate(data)
-        self.handler.assertLogsMessage(
-            "[E0] You may not change the person for the entitlement.",
-            level=logging.INFO)

=== modified file 'lib/lp/security.py'
--- lib/lp/security.py	2012-02-08 05:07:20 +0000
+++ lib/lp/security.py	2012-02-14 00:24:21 +0000
@@ -103,7 +103,6 @@
     IDistroSeriesDifferenceEdit,
     )
 from lp.registry.interfaces.distroseriesparent import IDistroSeriesParent
-from lp.registry.interfaces.entitlement import IEntitlement
 from lp.registry.interfaces.gpg import IGPGKey
 from lp.registry.interfaces.irc import IIrcID
 from lp.registry.interfaces.location import IPersonLocation
@@ -2249,26 +2248,6 @@
                 user.inTeam(self.obj.target_branch.reviewer))
 
 
-class ViewEntitlement(AuthorizationBase):
-    """Permissions to view IEntitlement objects.
-
-    Allow the owner of the entitlement, the entitlement registrant,
-    or any member of the team or any admin to view the entitlement.
-    """
-    permission = 'launchpad.View'
-    usedfor = IEntitlement
-
-    def checkAuthenticated(self, user):
-        """Is the user able to view an Entitlement attribute?
-
-        Any team member can edit a branch subscription for their team.
-        Launchpad Admins can also edit any branch subscription.
-        """
-        return (user.inTeam(self.obj.person) or
-                user.inTeam(self.obj.registrant) or
-                user.in_admin)
-
-
 class AdminDistroSeriesLanguagePacks(
     OnlyRosettaExpertsAndAdmins,
     EditDistroSeriesByReleaseManagerOrDistroOwnersOrAdmins):

=== removed file 'scripts/entitlements-to-lp.py'
--- scripts/entitlements-to-lp.py	2012-01-01 03:13:08 +0000
+++ scripts/entitlements-to-lp.py	1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-#!/usr/bin/python -S
-#
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# pylint: disable-msg=W0403
-import _pythonpath
-
-import logging
-import sys
-
-from lp.registry.scripts.entitlement import (
-    EntitlementExchange,
-    EntitlementImporter,
-    )
-from lp.services.scripts.base import LaunchpadScript
-
-
-class ImportEntitlementsScript(LaunchpadScript):
-    """Script for to import entitlement data into Launchpad."""
-
-    description = "Create or update entitlements."
-    usage = ("usage: %s [-c|--create | -u|--update] file_name" %
-             sys.argv[0])
-
-    loglevel = logging.INFO
-
-    def add_my_options(self):
-        """See `LaunchpadScript`."""
-        self.parser.add_option(
-            '-c', '--create', action='store_const', const='create',
-            help='Create new entitlements', dest='action')
-        self.parser.add_option(
-            '-u', '--update', action='store_const', const='update',
-            help='Update existing entitlements', dest='action')
-        self.parser.add_option(
-            '-f', '--infile', action='store', default='-',
-            help='Input file name ("-" for stdin)', dest='in_file_name')
-        self.parser.add_option(
-            '-o', '--outfile', action='store', default='-',
-            help='Output file name ("-" for stdout)', dest='out_file_name')
-
-    def main(self):
-        """See `LaunchpadScript`."""
-
-        action = self.options.action
-
-        if self.options.in_file_name == '-':
-            in_file = sys.stdin
-        else:
-            in_file = open(self.options.in_file_name, "rb")
-
-        if self.options.out_file_name == '-':
-            out_file = sys.stdout
-        else:
-            out_file = open(self.options.out_file_name, "wb")
-
-        # get a reader and writer
-        reader = EntitlementExchange.readerFactory(in_file)
-        entitlement_writer = EntitlementImporter(self.logger)
-        importer = EntitlementImporter(self.logger)
-        if action == 'create':
-            out_data = importer.createEntitlements(reader)
-        elif action == 'update':
-            out_data = importer.updateEntitlements(reader)
-        elif action is None:
-            self.logger.error("No action specified.  Use either -c or -u.")
-            return 1
-        else:
-            self.logger.error("Invalid action: %s\n" % action)
-            return 1
-
-        self.txn.commit()
-
-        if out_data:
-            writer = EntitlementExchange.writerFactory(out_file)
-            writer.writerows(out_data)
-        return 0
-
-if __name__ == '__main__':
-    script = ImportEntitlementsScript(
-        'lp.services.scripts.entitlements')
-    script.run()