From d16efcc6cf953c3e8f15fe5ea9fa0e35ce0471a7 Mon Sep 17 00:00:00 2001
From: Robert Sparks <rjsparks@nostrum.com>
Date: Fri, 21 Aug 2015 21:07:18 +0000
Subject: [PATCH] Refactor of MailToken to keep the lists of To and CC tokens
 with one object  - Legacy-Id: 10036

---
 ietf/mailtoken/admin.py                       |   2 +-
 ietf/mailtoken/migrations/0001_initial.py     |  10 +-
 .../migrations/0002_auto_20150809_1314.py     | 729 ++++++++----------
 ietf/mailtoken/models.py                      |   3 +-
 ietf/mailtoken/resources.py                   |   6 +-
 ietf/mailtoken/tests.py                       |   6 +-
 ietf/mailtoken/utils.py                       |  19 +-
 ietf/mailtoken/views.py                       |   6 +-
 ietf/name/fixtures/names.json                 | 588 ++++++--------
 ietf/templates/mailtoken/token.html           |  11 +-
 10 files changed, 591 insertions(+), 789 deletions(-)

diff --git a/ietf/mailtoken/admin.py b/ietf/mailtoken/admin.py
index 1330dab64..c58f4c551 100644
--- a/ietf/mailtoken/admin.py
+++ b/ietf/mailtoken/admin.py
@@ -12,6 +12,6 @@ admin.site.register(Recipient, RecipientAdmin)
 
 class MailTokenAdmin(admin.ModelAdmin):
     list_display = [ 'slug', 'desc',  ]
-    filter_horizontal = [ 'recipients' ]
+    filter_horizontal = [ 'to', 'cc',  ]
 admin.site.register(MailToken, MailTokenAdmin)
 
diff --git a/ietf/mailtoken/migrations/0001_initial.py b/ietf/mailtoken/migrations/0001_initial.py
index 3c22d2b85..bcfa776f2 100644
--- a/ietf/mailtoken/migrations/0001_initial.py
+++ b/ietf/mailtoken/migrations/0001_initial.py
@@ -35,8 +35,14 @@ class Migration(migrations.Migration):
         ),
         migrations.AddField(
             model_name='mailtoken',
-            name='recipients',
-            field=models.ManyToManyField(to='mailtoken.Recipient', null=True, blank=True),
+            name='cc',
+            field=models.ManyToManyField(related_name='used_in_cc', null=True, to='mailtoken.Recipient', blank=True),
+            preserve_default=True,
+        ),
+        migrations.AddField(
+            model_name='mailtoken',
+            name='to',
+            field=models.ManyToManyField(related_name='used_in_to', null=True, to='mailtoken.Recipient', blank=True),
             preserve_default=True,
         ),
     ]
diff --git a/ietf/mailtoken/migrations/0002_auto_20150809_1314.py b/ietf/mailtoken/migrations/0002_auto_20150809_1314.py
index 51b13175a..984c8b1a9 100644
--- a/ietf/mailtoken/migrations/0002_auto_20150809_1314.py
+++ b/ietf/mailtoken/migrations/0002_auto_20150809_1314.py
@@ -240,570 +240,509 @@ def make_mailtokens(apps):
     Recipient=apps.get_model('mailtoken','Recipient')
     MailToken=apps.get_model('mailtoken','MailToken')
 
-    def mt_factory(slug,desc,recipient_slugs):
+    def mt_factory(slug,desc,to_slugs,cc_slugs=[]):
         m = MailToken.objects.create(slug=slug, desc=desc)
-        m.recipients = Recipient.objects.filter(slug__in=recipient_slugs)
+        m.to = Recipient.objects.filter(slug__in=to_slugs)
+        m.cc = Recipient.objects.filter(slug__in=cc_slugs)
 
     mt_factory(slug='ballot_saved',
-               desc='Recipients when a new ballot position (with discusses, other blocking positions, or comments) is saved',
-               recipient_slugs=['iesg'])
-
-    mt_factory(slug='ballot_saved_cc',
-               desc='Copied when a new ballot position (with discusses, other blocking positions, or comments) is saved',
-               recipient_slugs=['doc_authors',
-                                'doc_group_chairs',
-                                'doc_shepherd',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                                'conflict_review_stream_manager',
-                                ])
+               desc="Recipients when a new ballot position "
+                    "(with discusses, other blocking positions, "
+                    "or comments) is saved",
+               to_slugs=['iesg'],
+               cc_slugs=['doc_authors',
+                         'doc_group_chairs',
+                         'doc_shepherd',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                         'conflict_review_stream_manager',
+                        ]
+              )
 
     mt_factory(slug='ballot_deferred',
-               desc='Recipients when a ballot is deferred to or undeferred from a future telechat',
-               recipient_slugs=['iesg',
-                                'iesg_secretary',
-                                'doc_group_chairs',
-                                'doc_notify',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                                'conflict_review_stream_manager',
-                                ])
+               desc="Recipients when a ballot is deferred to "
+                    "or undeferred from a future telechat",
+               to_slugs=['iesg',
+                         'iesg_secretary',
+                         'doc_group_chairs',
+                         'doc_notify',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                         'conflict_review_stream_manager',
+                        ],
+              )
 
     mt_factory(slug='ballot_approved_ietf_stream',
-               desc='Recipients when an IETF stream document ballot is approved',
-               recipient_slugs=['ietf_announce'])
-
-    mt_factory(slug='ballot_approved_ietf_stream_cc',
-               desc='Copied when an IETF stream document ballot is approved',
-               recipient_slugs=['iesg',
-                                'doc_notify',
-                                'doc_ad',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_group_mail_list',
-                                'doc_group_chairs',
-                                'rfc_editor',
-                                ])
+               desc="Recipients when an IETF stream document ballot is approved",
+               to_slugs=['ietf_announce'],
+               cc_slugs=['iesg',
+                         'doc_notify',
+                         'doc_ad',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_group_mail_list',
+                         'doc_group_chairs',
+                         'rfc_editor',
+                         ],
+              )
  
     mt_factory(slug='ballot_approved_ietf_stream_iana',
-               desc='Recipients for IANA message when an IETF stream document ballot is approved',
-               recipient_slugs=['iana_approve'])
+               desc="Recipients for IANA message when an IETF stream document ballot is approved",
+               to_slugs=['iana_approve'])
 
     mt_factory(slug='ballot_approved_conflrev',
-               desc='Recipients when a conflict review ballot is approved',
-               recipient_slugs=['conflict_review_stream_manager',
-                                'conflict_review_steering_group',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                                'doc_notify',
-                                ])
-
-    mt_factory(slug='ballot_approved_conflrev_cc',
-               desc='Copied when a conflict review ballot is approved',
-               recipient_slugs=['iesg',
-                                'ietf_announce',
-                                'iana',
-                                ])
+               desc="Recipients when a conflict review ballot is approved",
+               to_slugs=['conflict_review_stream_manager',
+                         'conflict_review_steering_group',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                         'doc_notify',
+                        ],
+               cc_slugs=['iesg',
+                         'ietf_announce',
+                         'iana',
+                        ],
+              )
 
     mt_factory(slug='ballot_approved_charter',
-               desc='Recipients when a charter is approved',
-               recipient_slugs=['ietf_announce',])
-            
-    mt_factory(slug='ballot_approved_charter_cc',
-               desc='Copied when a charter is approved',
-               recipient_slugs=['group_mail_list',
-                                'group_steering_group',
-                                'group_chairs',
-                                'doc_notify',
-                               ])
+               desc="Recipients when a charter is approved",
+               to_slugs=['ietf_announce',],
+               cc_slugs=['group_mail_list',
+                         'group_steering_group',
+                         'group_chairs',
+                         'doc_notify',
+                        ],
+              )
             
     mt_factory(slug='ballot_approved_status_change',
-               desc='Recipients when a status change is approved',
-               recipient_slugs=['ietf_announce',])
-            
-    mt_factory(slug='ballot_approved_status_change_cc',
-               desc='Copied when a status change is approved',
-               recipient_slugs=['iesg',
-                                'rfc_editor',
-                                'doc_notify',
-                                'doc_affectddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                               ])
+               desc="Recipients when a status change is approved",
+               to_slugs=['ietf_announce',],
+               cc_slugs=['iesg',
+                         'rfc_editor',
+                         'doc_notify',
+                         'doc_affectddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ],
+              )
 
     mt_factory(slug='last_call_requested',
-               desc='Recipients when AD requests a last call',
-               recipient_slugs=['iesg_secretary',])
-
-    mt_factory(slug='last_call_requested_cc',
-               desc='Copied when AD requests a last call',
-               recipient_slugs=['doc_ad',
-                                'doc_shepherd',
-                                'doc_notify'])
+               desc="Recipients when AD requests a last call",
+               to_slugs=['iesg_secretary',],
+               cc_slugs=['doc_ad',
+                         'doc_shepherd',
+                         'doc_notify',
+                        ],
+              )
 
     mt_factory(slug='last_call_issued',
-               desc='Recipients when a last call is issued',
-               recipient_slugs=['ietf_announce',])
-
-    mt_factory(slug='last_call_issued_cc',
-               desc='Copied when a last call is issued',
-               recipient_slugs=['doc_ad',
-                                'doc_shepherd',
-                                'doc_authors',
-                                'doc_notify',
-                                'doc_group_list_email',
-                                'doc_group_chairs',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify'])
+               desc="Recipients when a last call is issued",
+               to_slugs=['ietf_announce',],
+               cc_slugs=['doc_ad',
+                         'doc_shepherd',
+                         'doc_authors',
+                         'doc_notify',
+                         'doc_group_list_email',
+                         'doc_group_chairs',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ]
+              )
 
     mt_factory(slug='last_call_issued_iana',
-               desc='Recipients for IANA message when a last call is issued',
-               recipient_slugs=['iana_last_call'])
+               desc="Recipients for IANA message when a last call is issued",
+               to_slugs=['iana_last_call'])
 
     mt_factory(slug='last_call_expired',
-               desc='Recipients when a last call has expired',
-               recipient_slugs=['iesg',
-                                'doc_notify',
-                                'doc_authors',
-                                'doc_shepherd',
-                               ])
-
-    mt_factory(slug='last_call_expired_cc',
-               desc='Copied when a last call has expired',
-               recipient_slugs=['iesg_secretary',])
+               desc="Recipients when a last call has expired",
+               to_slugs=['iesg',
+                         'doc_notify',
+                         'doc_authors',
+                         'doc_shepherd',
+                        ],
+               cc_slugs=['iesg_secretary',],
+              )
 
     mt_factory(slug='pubreq_iesg',
-               desc='Recipients when a draft is submitted to the IESG',
-               recipient_slugs=['doc_ad',])
-
-    mt_factory(slug='pubreq_iesg_cc',
-               desc='Copied when a draft is submitted to the IESG',
-               recipient_slugs=['iesg_secretary',
-                                'doc_notify',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                               ])
+               desc="Recipients when a draft is submitted to the IESG",
+               to_slugs=['doc_ad',],
+               cc_slugs=['iesg_secretary',
+                         'doc_notify',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                        ],
+              )
 
     mt_factory(slug='pubreq_rfced',
-               desc='Recipients when a non-IETF stream manager requests publication',
-               recipient_slugs=['rfc_editor',
-                               ])
+               desc="Recipients when a non-IETF stream manager requests publication",
+               to_slugs=['rfc_editor',])
 
     mt_factory(slug='pubreq_rfced_iana',
-               desc='Recipients for IANA message when a non-IETF stream manager requests publication',
-               recipient_slugs=['iana_approve',])
+               desc="Recipients for IANA message when a non-IETF stream manager "
+                    "requests publication",
+               to_slugs=['iana_approve',])
 
     mt_factory(slug='charter_external_review',
-               desc='Recipients for a charter external review',
-               recipient_slugs=['ietf_announce',]) 
-
-    mt_factory(slug='charter_external_review_cc',
-               desc='Copied on a charter external review',
-               recipient_slugs=['group_mail_list',]) 
+               desc="Recipients for a charter external review",
+               to_slugs=['ietf_announce',],
+               cc_slugs=['group_mail_list',], 
+              ) 
 
     mt_factory(slug='conflrev_requested',
                desc="Recipients for a stream manager's request for an IETF conflict review",
-               recipient_slugs=['iesg_secretary'])
-
-    mt_factory(slug='conflrev_requested_cc',
-               desc="Copied on a stream manager's request for an IETF conflict review",
-               recipient_slugs=['iesg',
-                                'doc_notify',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                               ])
+               to_slugs=['iesg_secretary'],
+               cc_slugs=['iesg',
+                         'doc_notify',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ],
+              )
 
     mt_factory(slug='conflrev_requested_iana',
-               desc="Recipients for IANA message when a stream manager requests an IETF conflict review",
-               recipient_slugs=['iana_eval',])
+               desc="Recipients for IANA message when a stream manager requests "
+                    "an IETF conflict review",
+               to_slugs=['iana_eval',])
 
     mt_factory(slug='doc_stream_changed',
                desc="Recipients for notification when a document's stream changes",
-               recipient_slugs=['stream_managers',
-                                'doc_notify',
-                               ])
+               to_slugs=['stream_managers',
+                         'doc_notify',
+                        ])
 
     mt_factory(slug='doc_stream_state_edited',
                desc="Recipients when the stream state of a document is manually edited",
-               recipient_slugs=['doc_group_chairs',
-                                'doc_group_delegates',
-                                'doc_shepherd',
-                                'doc_authors',
-                               ]) 
+               to_slugs=['doc_group_chairs',
+                         'doc_group_delegates',
+                         'doc_shepherd',
+                         'doc_authors',
+                        ]) 
 
     mt_factory(slug='group_milestones_edited',
                desc="Recipients when any of a group's milestones are edited",
-               recipient_slugs=['group_responsible_directors',
-                                'group_chairs',
-                               ])
+               to_slugs=['group_responsible_directors',
+                         'group_chairs',
+                        ])
                
     mt_factory(slug='group_approved_milestones_edited',
                desc="Recipients when the set of approved milestones for a group are edited",
-               recipient_slugs=['group_mail_list',
-                               ])
+               to_slugs=['group_mail_list',
+                        ])
 
     mt_factory(slug='doc_state_edited',
                desc="Recipients when a document's state is manually edited",
-               recipient_slugs=['doc_notify',
-                                'doc_ad',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                               ])
+               to_slugs=['doc_notify',
+                         'doc_ad',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ])
 
     mt_factory(slug='doc_iana_state_changed',
                desc="Recipients when IANA state information for a document changes ",
-               recipient_slugs=['doc_notify',
-                                'doc_ad',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                               ])
+               to_slugs=['doc_notify',
+                         'doc_ad',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ])
 
     mt_factory(slug='doc_telechat_details_changed',
-               desc="Recipients when a document's telechat date or other telechat specific details are changed",
-               recipient_slugs=['iesg',
-                                'iesg_secretary',
-                                'doc_notify',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_affecteddoc_authors',
-                                'doc_affecteddoc_group_chairs',
-                                'doc_affecteddoc_notify',
-                               ])
+               desc="Recipients when a document's telechat date or other "
+                    "telechat specific details are changed",
+               to_slugs=['iesg',
+                         'iesg_secretary',
+                         'doc_notify',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_affecteddoc_authors',
+                         'doc_affecteddoc_group_chairs',
+                         'doc_affecteddoc_notify',
+                        ])
 
     mt_factory(slug='doc_pulled_from_rfc_queue',
-               desc="Recipients when a document is taken out of the RFC's editor queue before publication",
-               recipient_slugs=['iana',
-                                'rfc_editor',
-                               ])
-
-    mt_factory(slug='doc_pulled_from_rfc_queue_cc',
-               desc="Recipients when a document is taken out of the RFC's editor queue before publication",
-               recipient_slugs=['iesg_secretary',
-                                'doc_ad', 
-                                'doc_notify',
-                                'doc_authors',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                               ])
+               desc="Recipients when a document is taken out of the RFC's editor queue "
+                    "before publication",
+               to_slugs=['iana',
+                         'rfc_editor',
+                        ],
+               cc_slugs=['iesg_secretary',
+                         'doc_ad', 
+                         'doc_notify',
+                         'doc_authors',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                        ],
+              )
 
     mt_factory(slug='doc_replacement_changed',
                desc="Recipients when what a document replaces or is replaced by changes",
-               recipient_slugs=['doc_authors',
-                                'doc_notify',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_group_responsible_directors',
-                               ]) 
+               to_slugs=['doc_authors',
+                         'doc_notify',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_group_responsible_directors',
+                        ]) 
 
     mt_factory(slug='charter_state_edit_admin_needed',
-               desc="Recipients for message to adminstrators when a charter state edit needs followon administrative action",
-               recipient_slugs=['iesg_secretary'])
+               desc="Recipients for message to adminstrators when a charter state edit "
+                    "needs followon administrative action",
+               to_slugs=['iesg_secretary'])
 
     mt_factory(slug='group_closure_requested',
                desc="Recipients for message requesting closure of a group",
-               recipient_slugs=['iesg_secretary'])
+               to_slugs=['iesg_secretary'])
 
     mt_factory(slug='doc_expires_soon',
                desc="Recipients for notification of impending expiration of a document",
-               recipient_slugs=['doc_authors'])
-
-    mt_factory(slug='doc_expires_soon_cc',
-               desc="Copied on  notification of impending expiration of a document",
-               recipient_slugs=['doc_notify',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_group_responsible_directors',
-                               ])
+               to_slugs=['doc_authors'],
+               cc_slugs=['doc_notify',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_group_responsible_directors',
+                        ],
+              )
 
     mt_factory(slug='doc_expired',
                desc="Recipients for notification of a document's expiration",
-               recipient_slugs=['doc_authors'])
-
-    mt_factory(slug='doc_expired_cc',
-               desc="Copied on notification of a document's expiration",
-               recipient_slugs=['doc_notify',
-                                'doc_shepherd',
-                                'doc_group_chairs',
-                                'doc_group_responsible_directors',
-                               ])
+               to_slugs=['doc_authors'],
+               cc_slugs=['doc_notify',
+                         'doc_shepherd',
+                         'doc_group_chairs',
+                         'doc_group_responsible_directors',
+                        ],
+              )
 
     mt_factory(slug='resurrection_requested',
                desc="Recipients of a request to change the state of a draft away from 'Dead'",
-               recipient_slugs=['internet_draft_requests',])
+               to_slugs=['internet_draft_requests',])
 
     mt_factory(slug='resurrection_completed',
                desc="Recipients when a draft resurrection request has been completed",
-               recipient_slugs=['iesg_secretary',
-                                'doc_ad',
-                               ])
+               to_slugs=['iesg_secretary',
+                         'doc_ad',
+                        ])
 
     mt_factory(slug='sub_manual_post_requested',
                desc="Recipients for a manual post request for a draft submission",
-               recipient_slugs=['internet_draft_requests',
-                               ])
-
-    mt_factory(slug='sub_manual_post_requested_cc',
-               desc="Copied on a manual post request for a draft submission",
-               recipient_slugs=['submission_submitter',
-                                'submission_authors',
-                                'submission_group_chairs',
-                               ])
+               to_slugs=['internet_draft_requests',],
+               cc_slugs=['submission_submitter',
+                         'submission_authors',
+                         'submission_group_chairs',
+                        ],
+              )
 
     mt_factory(slug='sub_chair_approval_requested',
-               desc="Recipients for a message requesting group chair approval of a draft submission",
-               recipient_slugs=['submission_group_chairs',])
+               desc="Recipients for a message requesting group chair approval of "
+                    "a draft submission",
+               to_slugs=['submission_group_chairs',])
 
     mt_factory(slug='sub_confirmation_requested',
                desc="Recipients for a message requesting confirmation of a draft submission",
-               recipient_slugs=['submission_confirmers',])
+               to_slugs=['submission_confirmers',])
 
     mt_factory(slug='sub_management_url_requested',
                desc="Recipients for a message with the full URL for managing a draft submission",
-               recipient_slugs=['submission_confirmers',])
+               to_slugs=['submission_confirmers',])
 
     mt_factory(slug='sub_announced',
                desc="Recipients for the announcement of a successfully submitted draft",
-               recipient_slugs=['ietf_announce',
-                               ])
-
-    mt_factory(slug='sub_announced_cc',
-               desc="Copied on the announcement of a successfully submitted draft",
-               recipient_slugs=['submission_group_mail_list',
-                               ])
+               to_slugs=['ietf_announce',
+                        ],
+               cc_slugs=['submission_group_mail_list',
+                        ],
+              )
 
     mt_factory(slug='sub_announced_to_authors',
-               desc="Recipients for the announcement to the authors of a successfully submitted draft",
-               recipient_slugs=['submission_authors',
-                                'submission_confirmers',
-                               ])
+               desc="Recipients for the announcement to the authors of a successfully "
+                    "submitted draft",
+               to_slugs=['submission_authors',
+                         'submission_confirmers',
+                        ])
 
     mt_factory(slug='sub_new_version',
                desc="Recipients for notification of a new version of an existing document",
-               recipient_slugs=['doc_notify',
-                                'doc_ad',
-                                'non_ietf_stream_manager',
-                                'rfc_editor_if_doc_in_queue',
-                                'doc_discussing_ads',
-                               ])
+               to_slugs=['doc_notify',
+                         'doc_ad',
+                         'non_ietf_stream_manager',
+                         'rfc_editor_if_doc_in_queue',
+                         'doc_discussing_ads',
+                        ])
 
     mt_factory(slug='milestone_review_reminder',
                desc="Recipients for reminder message that unapproved milestone changes need review",
-               recipient_slugs=['group_responsible_directors',
-                               ])
-
-    mt_factory(slug='milestone_review_reminder_cc',
-               desc="Copied on reminder message that unapproved milestone changes need review",
-               recipient_slugs=['group_chairs',
-                               ])
+               to_slugs=['group_responsible_directors',],
+               cc_slugs=['group_chairs', ],
+              )
 
     mt_factory(slug='milestones_due_soon',
-               desc='Recipients for reminder message for milestones about to become overdue',
-               recipient_slugs=['group_chairs',
-                               ])
+               desc="Recipients for reminder message for milestones about to become overdue",
+               to_slugs=['group_chairs', ])
 
     mt_factory(slug='milestones_overdue',
-               desc='Recipients for message about milestones that are overdue',
-               recipient_slugs=['group_chairs',
-                               ])
+               desc="Recipients for message about milestones that are overdue",
+               to_slugs=['group_chairs', ])
 
     mt_factory(slug='group_personnel_change',
                desc="Recipients for a message noting changes in a group's personnel",
-               recipient_slugs=['iesg_secretary',
-                                'group_responsible_directors',
-                                'group_chairs',
-                                'group_changed_personnel',
-                               ])
+               to_slugs=['iesg_secretary',
+                         'group_responsible_directors',
+                         'group_chairs',
+                         'group_changed_personnel',
+                        ])
 
     mt_factory(slug='session_requested',
                desc="Recipients for a normal meeting session request",
-               recipient_slugs=['session_requests',
-                               ]) 
-
-    mt_factory(slug='session_requested_cc',
-               desc="Copied on a normal meeting session request",
-               recipient_slugs=['group_mail_list',
-                                'group_chairs',
-                                'group_responsible_directors',
-                                'logged_in_person',
-                               ]) 
+               to_slugs=['session_requests', ], 
+               cc_slugs=['group_mail_list',
+                         'group_chairs',
+                         'group_responsible_directors',
+                         'logged_in_person',
+                        ],
+              ) 
 
     mt_factory(slug='session_requested_long',
                desc="Recipients for a meeting session request for more than 2 sessions",
-               recipient_slugs=['group_responsible_directors',
-                               ])
-     
-    mt_factory(slug='session_requested_long_cc',
-               desc="Copied on a meeting session request for more than 2 sessions",
-               recipient_slugs=['session_requests',
-                                'group_chairs',
-                                'logged_in_person',
-                               ])
+               to_slugs=['group_responsible_directors', ],
+               cc_slugs=['session_requests',
+                         'group_chairs',
+                         'logged_in_person',
+                               ],
+              )
 
     mt_factory(slug='session_request_cancelled',
                desc="Recipients for a message cancelling a session request",
-               recipient_slugs=['session_requests',
-                               ])
-
-    mt_factory(slug='session_request_cancelled_cc',
-               desc="Copied on a message cancelling a session request",
-               recipient_slugs=['group_mail_list',
-                                'group_chairs',
-                                'group_responsible_directors',
-                                'logged_in_person',
-                               ]) 
+               to_slugs=['session_requests', ],
+               cc_slugs=['group_mail_list',
+                         'group_chairs',
+                         'group_responsible_directors',
+                         'logged_in_person',
+                        ],
+              )
 
     mt_factory(slug='session_request_not_meeting',
                desc="Recipients for a message noting a group plans to not meet",
-               recipient_slugs=['session_requests',
-                               ])
-
-    mt_factory(slug='session_request_not_meeting_cc',
-               desc="Copied on a message noting a group plans to not meet",
-               recipient_slugs=['group_mail_list',
-                                'group_chairs',
-                                'group_responsible_directors',
-                                'logged_in_person',
-                               ]) 
+               to_slugs=['session_requests', ],
+               cc_slugs=['group_mail_list',
+                         'group_chairs',
+                         'group_responsible_directors',
+                         'logged_in_person',
+                        ], 
+              )
 
     mt_factory(slug='session_scheduled',
                desc="Recipients for details when a session has been scheduled",
-               recipient_slugs=['session_requester',
-                                'group_chairs',
-                               ])
-
-    mt_factory(slug='session_scheduled_cc',
-               desc="Recipients for details when a session has been scheduled",
-               recipient_slugs=['group_mail_list',
-                                'group_responsible_directors',
-                               ])
+               to_slugs=['session_requester',
+                         'group_chairs',
+                        ],
+               cc_slugs=['group_mail_list',
+                         'group_responsible_directors',
+                        ],
+              )
 
     mt_factory(slug='ipr_disclosure_submitted',
                desc="Recipients when an IPR disclosure is submitted",
-               recipient_slugs=['ipr_requests',
-                               ])
+               to_slugs=['ipr_requests', ])
 
     mt_factory(slug='ipr_disclosure_followup',
                desc="Recipients when the secretary follows up on an IPR disclosure submission",
-               recipient_slugs=['ipr_submitter',
-                               ])
-
-    mt_factory(slug='ipr_disclosure_followup_cc',
-               desc="Copied when the secretary follows up on an IPR disclosure submission",
-               recipient_slugs=[])
+               to_slugs=['ipr_submitter', ],)
 
     mt_factory(slug='ipr_posting_confirmation',
                desc="Recipients for a message confirming that a disclosure has been posted",
-               recipient_slugs=['ipr_submitter',
-                               ])
-
-    mt_factory(slug='ipr_posting_confirmation_cc',
-               desc="Copied on a message confirming that a disclosure has been posted",
-               recipient_slugs=['ipr_updatedipr_contacts',
-                                'ipr_updatedipr_holders',
-                               ])
+               to_slugs=['ipr_submitter', ],
+               cc_slugs=['ipr_updatedipr_contacts',
+                         'ipr_updatedipr_holders',
+                        ],
+              )
 
     mt_factory(slug='ipr_posted_on_doc',
                desc="Recipients when an IPR disclosure calls out a given document",
-               recipient_slugs=['doc_authors',
-                               ]) 
-
-    mt_factory(slug='ipr_posted_on_doc_cc',
-               desc="Copied when an IPR disclosure calls out a given document",
-               recipient_slugs=['doc_ipr_group_or_ad',
-                                'ipr_announce',
-                               ]) 
+               to_slugs=['doc_authors', ], 
+               cc_slugs=['doc_ipr_group_or_ad',
+                         'ipr_announce',
+                        ], 
+              )
 
     mt_factory(slug='liaison_statement_posted',
                desc="Recipient for a message when a new liaison statement is posted",
-               recipient_slugs=['liaison_to_contact',
-                               ])
-
-    mt_factory(slug='liaison_statement_posted_cc',
-               desc="Copied on a message when a new liaison statement is posted",
-               recipient_slugs=['liaison_cc',
-                                'liaison_technical_contact',
-                                'liaison_response_contact',
-                               ])
+               to_slugs=['liaison_to_contact', ],
+               cc_slugs=['liaison_cc',
+                         'liaison_technical_contact',
+                         'liaison_response_contact',
+                        ],
+              )
 
     mt_factory(slug='liaison_approval_requested',
                desc="Recipients for a message that a pending liaison statement needs approval",
-               recipient_slugs=['liaison_statements_list',
-                               ])
+               to_slugs=['liaison_statements_list',
+                        ])
 
     mt_factory(slug='liaison_deadline_soon',
-               desc="Recipients for a message about a liaison statement deadline that is approaching.",
-               recipient_slugs=['liaison_to_contact',
-                               ])
-
-    mt_factory(slug='liaison_deadline_soon_cc',
-               desc="Copied on a message about a liaison statement deadline that is approaching.",
-               recipient_slugs=['liaison_cc',
-                                'liaison_technical_contact',
-                                'liaison_response_contact',
-                               ])
+               desc="Recipients for a message about a liaison statement deadline that is "
+                    "approaching.",
+               to_slugs=['liaison_to_contact',
+                        ],
+               cc_slugs=['liaison_cc',
+                         'liaison_technical_contact',
+                         'liaison_response_contact',
+                        ],
+              )
 
     mt_factory(slug='liaison_manager_update_request',
                desc="Recipients for a message requesting an updated list of authorized individuals",
-               recipient_slugs=['liaison_manager',
-                               ])
+               to_slugs=['liaison_manager', ])
 
     mt_factory(slug='nomination_received',
                desc="Recipients for a message noting a new nomination has been received",
-               recipient_slugs=['nomcom_chair',
-                               ])
+               to_slugs=['nomcom_chair', ])
 
     mt_factory(slug='nomination_receipt_requested',
                desc="Recipients for a message confirming a nomination was made",
-               recipient_slugs=['nominator', 
-                               ])
+               to_slugs=['nominator', ])
 
     mt_factory(slug='nomcom_comment_receipt_requested',
                desc="Recipients for a message confirming a comment was made",
-               recipient_slugs=['commenter', 
-                               ])
+               to_slugs=['commenter', ])
 
     mt_factory(slug='nomination_created_person',
                desc="Recipients for a message noting that a nomination caused a "
                      "new Person record to be created in the datatracker",
-               recipient_slugs=['ietf_secretariat',
-                                'nomcom_chair',
-                               ])
+               to_slugs=['ietf_secretariat',
+                         'nomcom_chair',
+                        ],
+              )
+
     mt_factory(slug='nomination_new_nominee',
                desc="Recipients the first time a person is nominated for a position, "
                      "asking them to accept or decline the nomination",
-               recipient_slugs=['nominee',
-                               ])
+               to_slugs=['nominee', ])
 
     mt_factory(slug='nomination_accept_reminder',
                desc="Recipeints of message reminding a nominee to accept or decline a nomination",
-               recipient_slugs=['nominee',
-                               ])
+               to_slugs=['nominee', ])
 
     mt_factory(slug='nomcom_questionnaire',
                desc="Recipients for the questionairre that nominees should complete",
-               recipient_slugs=['nominee',
-                               ])
+               to_slugs=['nominee', ])
 
     mt_factory(slug='nomcom_questionnaire_reminder',
-               desc="Recipients for a message reminding a nominee to return a completed questionairre response",
-               recipient_slugs=['nominee',
-                               ])
+               desc="Recipients for a message reminding a nominee to return a "
+                    "completed questionairre response",
+               to_slugs=['nominee', ])
 
 def forward(apps, schema_editor):
 
diff --git a/ietf/mailtoken/models.py b/ietf/mailtoken/models.py
index e89c8ad7c..ee393a830 100644
--- a/ietf/mailtoken/models.py
+++ b/ietf/mailtoken/models.py
@@ -8,7 +8,8 @@ from ietf.group.models import Role
 class MailToken(models.Model):
     slug = models.CharField(max_length=32, primary_key=True)
     desc = models.TextField(blank=True)
-    recipients = models.ManyToManyField('Recipient', null=True, blank=True)
+    to   = models.ManyToManyField('Recipient', null=True, blank=True, related_name='used_in_to')
+    cc   = models.ManyToManyField('Recipient', null=True, blank=True, related_name='used_in_cc')
 
     class Meta:
         ordering = ["slug"]
diff --git a/ietf/mailtoken/resources.py b/ietf/mailtoken/resources.py
index 98f9ed7d3..8a46af244 100644
--- a/ietf/mailtoken/resources.py
+++ b/ietf/mailtoken/resources.py
@@ -20,14 +20,16 @@ class RecipientResource(ModelResource):
 api.mailtoken.register(RecipientResource())
 
 class MailTokenResource(ModelResource):
-    recipients      = ToManyField(RecipientResource, 'recipients', null=True)
+    to      = ToManyField(RecipientResource, 'to', null=True)
+    cc      = ToManyField(RecipientResource, 'cc', null=True)
     class Meta:
         queryset = MailToken.objects.all()
         #resource_name = 'mailtoken'
         filtering = { 
             "slug": ALL,
             "desc": ALL,
-            "recipients": ALL_WITH_RELATIONS,
+            "to": ALL_WITH_RELATIONS,
+            "cc": ALL_WITH_RELATIONS,
         }
 api.mailtoken.register(MailTokenResource())
 
diff --git a/ietf/mailtoken/tests.py b/ietf/mailtoken/tests.py
index 2a9eeb944..e16a46fa6 100644
--- a/ietf/mailtoken/tests.py
+++ b/ietf/mailtoken/tests.py
@@ -13,12 +13,12 @@ class EventMailTests(TestCase):
         url = urlreverse('ietf.mailtoken.views.show_tokens')
         r = self.client.get(url)
         self.assertEqual(r.status_code, 200)
-        self.assertTrue('ballot_saved_cc' in r.content)
+        self.assertTrue('ballot_saved' in r.content)
    
-        url = urlreverse('ietf.mailtoken.views.show_tokens',kwargs=dict(mailtoken_slug='ballot_saved_cc'))
+        url = urlreverse('ietf.mailtoken.views.show_tokens',kwargs=dict(mailtoken_slug='ballot_saved'))
         r = self.client.get(url)
         self.assertEqual(r.status_code, 200)
-        self.assertTrue('ballot_saved_cc' in r.content)
+        self.assertTrue('ballot_saved' in r.content)
 
     def test_show_recipients(self):
 
diff --git a/ietf/mailtoken/utils.py b/ietf/mailtoken/utils.py
index 56b330082..d469e730f 100644
--- a/ietf/mailtoken/utils.py
+++ b/ietf/mailtoken/utils.py
@@ -1,20 +1,17 @@
-from django.core.exceptions import ObjectDoesNotExist
-
 from ietf.mailtoken.models import MailToken, Recipient
 
 def gather_address_list(slug,**kwargs):
     
     addrs = []
 
-    try:
-       mailtoken = MailToken.objects.get(slug=slug)
-    except ObjectDoesNotExist:
-       # TODO remove the raise here, or find a better way to detect runtime misconfiguration
-       raise
-       return addrs
-
-    for recipient in mailtoken.recipients.all():
-        addrs.extend(recipient.gather(**kwargs))
+    if slug.endswith('_cc'):
+        mailtoken = MailToken.objects.get(slug=slug[:-3])
+        for recipient in mailtoken.cc.all():
+            addrs.extend(recipient.gather(**kwargs))
+    else:
+        mailtoken = MailToken.objects.get(slug=slug)
+        for recipient in mailtoken.to.all():
+            addrs.extend(recipient.gather(**kwargs))
 
     return list(set([addr for addr in addrs if addr]))
 
diff --git a/ietf/mailtoken/views.py b/ietf/mailtoken/views.py
index 1341f76f0..66d45a298 100644
--- a/ietf/mailtoken/views.py
+++ b/ietf/mailtoken/views.py
@@ -2,19 +2,21 @@
 
 from inspect import getsourcelines
 
-from django.shortcuts import render
+from django.shortcuts import render, get_object_or_404
 
 from ietf.mailtoken.models import MailToken, Recipient
 
 def show_tokens(request, mailtoken_slug=None):
     mailtokens = MailToken.objects.all()
     if mailtoken_slug:
-        mailtokens = mailtokens.filter(slug=mailtoken_slug) # TODO better 404 behavior here and below
+        get_object_or_404(MailToken,slug=mailtoken_slug)
+        mailtokens = mailtokens.filter(slug=mailtoken_slug) 
     return render(request,'mailtoken/token.html',{'mailtoken_slug':mailtoken_slug,
                                                   'mailtokens':mailtokens})
 def show_recipients(request, recipient_slug=None):
     recipients = Recipient.objects.all()
     if recipient_slug:
+        get_object_or_404(Recipient,slug=recipient_slug)
         recipients = recipients.filter(slug=recipient_slug)
     for recipient in recipients:
         fname = 'gather_%s'%recipient.slug
diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json
index 49bf95d49..1a7bb6446 100644
--- a/ietf/name/fixtures/names.json
+++ b/ietf/name/fixtures/names.json
@@ -4777,7 +4777,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_notify",
+   "group_chairs",
+   "group_mail_list",
+   "group_steering_group"
+  ],
+  "to": [
    "ietf_announce"
   ],
   "desc": "Recipients when a charter is approved"
@@ -4787,20 +4793,12 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_notify",
-   "group_chairs",
-   "group_mail_list",
-   "group_steering_group"
+  "cc": [
+   "iana",
+   "iesg",
+   "ietf_announce"
   ],
-  "desc": "Copied when a charter is approved"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ballot_approved_charter_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "conflict_review_steering_group",
    "conflict_review_stream_manager",
    "doc_affecteddoc_authors",
@@ -4815,29 +4813,7 @@
 },
 {
  "fields": {
-  "recipients": [
-   "iana",
-   "iesg",
-   "ietf_announce"
-  ],
-  "desc": "Copied when a conflict review ballot is approved"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ballot_approved_conflrev_cc"
-},
-{
- "fields": {
-  "recipients": [
-   "ietf_announce"
-  ],
-  "desc": "Recipients when an IETF stream document ballot is approved"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ballot_approved_ietf_stream"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [
    "doc_ad",
    "doc_authors",
    "doc_group_chairs",
@@ -4847,14 +4823,18 @@
    "iesg",
    "rfc_editor"
   ],
-  "desc": "Copied when an IETF stream document ballot is approved"
+  "to": [
+   "ietf_announce"
+  ],
+  "desc": "Recipients when an IETF stream document ballot is approved"
  },
  "model": "mailtoken.mailtoken",
- "pk": "ballot_approved_ietf_stream_cc"
+ "pk": "ballot_approved_ietf_stream"
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iana_approve"
   ],
   "desc": "Recipients for IANA message when an IETF stream document ballot is approved"
@@ -4864,7 +4844,14 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_affecteddoc_group_chairs",
+   "doc_affecteddoc_notify",
+   "doc_notify",
+   "iesg",
+   "rfc_editor"
+  ],
+  "to": [
    "ietf_announce"
   ],
   "desc": "Recipients when a status change is approved"
@@ -4874,21 +4861,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_affecteddoc_group_chairs",
-   "doc_affecteddoc_notify",
-   "doc_notify",
-   "iesg",
-   "rfc_editor"
-  ],
-  "desc": "Copied when a status change is approved"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ballot_approved_status_change_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "conflict_review_stream_manager",
    "doc_affecteddoc_authors",
    "doc_affecteddoc_group_chairs",
@@ -4907,7 +4881,16 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "conflict_review_stream_manager",
+   "doc_affecteddoc_authors",
+   "doc_affecteddoc_group_chairs",
+   "doc_affecteddoc_notify",
+   "doc_authors",
+   "doc_group_chairs",
+   "doc_shepherd"
+  ],
+  "to": [
    "iesg"
   ],
   "desc": "Recipients when a new ballot position (with discusses, other blocking positions, or comments) is saved"
@@ -4917,23 +4900,10 @@
 },
 {
  "fields": {
-  "recipients": [
-   "conflict_review_stream_manager",
-   "doc_affecteddoc_authors",
-   "doc_affecteddoc_group_chairs",
-   "doc_affecteddoc_notify",
-   "doc_authors",
-   "doc_group_chairs",
-   "doc_shepherd"
+  "cc": [
+   "group_mail_list"
   ],
-  "desc": "Copied when a new ballot position (with discusses, other blocking positions, or comments) is saved"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ballot_saved_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "ietf_announce"
   ],
   "desc": "Recipients for a charter external review"
@@ -4943,17 +4913,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "group_mail_list"
-  ],
-  "desc": "Copied on a charter external review"
- },
- "model": "mailtoken.mailtoken",
- "pk": "charter_external_review_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iesg_secretary"
   ],
   "desc": "Recipients for message to adminstrators when a charter state edit needs followon administrative action"
@@ -4963,7 +4924,14 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_affecteddoc_authors",
+   "doc_affecteddoc_group_chairs",
+   "doc_affecteddoc_notify",
+   "doc_notify",
+   "iesg"
+  ],
+  "to": [
    "iesg_secretary"
   ],
   "desc": "Recipients for a stream manager's request for an IETF conflict review"
@@ -4973,21 +4941,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_affecteddoc_authors",
-   "doc_affecteddoc_group_chairs",
-   "doc_affecteddoc_notify",
-   "doc_notify",
-   "iesg"
-  ],
-  "desc": "Copied on a stream manager's request for an IETF conflict review"
- },
- "model": "mailtoken.mailtoken",
- "pk": "conflrev_requested_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iana_eval"
   ],
   "desc": "Recipients for IANA message when a stream manager requests an IETF conflict review"
@@ -4997,7 +4952,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_group_chairs",
+   "doc_group_responsible_directors",
+   "doc_notify",
+   "doc_shepherd"
+  ],
+  "to": [
    "doc_authors"
   ],
   "desc": "Recipients for notification of a document's expiration"
@@ -5007,20 +4968,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
    "doc_group_chairs",
    "doc_group_responsible_directors",
    "doc_notify",
    "doc_shepherd"
   ],
-  "desc": "Copied on notification of a document's expiration"
- },
- "model": "mailtoken.mailtoken",
- "pk": "doc_expired_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "doc_authors"
   ],
   "desc": "Recipients for notification of impending expiration of a document"
@@ -5030,20 +4984,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_group_chairs",
-   "doc_group_responsible_directors",
-   "doc_notify",
-   "doc_shepherd"
-  ],
-  "desc": "Copied on  notification of impending expiration of a document"
- },
- "model": "mailtoken.mailtoken",
- "pk": "doc_expires_soon_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_ad",
    "doc_affecteddoc_authors",
    "doc_affecteddoc_group_chairs",
@@ -5060,7 +5002,15 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_ad",
+   "doc_authors",
+   "doc_group_chairs",
+   "doc_notify",
+   "doc_shepherd",
+   "iesg_secretary"
+  ],
+  "to": [
    "iana",
    "rfc_editor"
   ],
@@ -5071,22 +5021,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_ad",
-   "doc_authors",
-   "doc_group_chairs",
-   "doc_notify",
-   "doc_shepherd",
-   "iesg_secretary"
-  ],
-  "desc": "Recipients when a document is taken out of the RFC's editor queue before publication"
- },
- "model": "mailtoken.mailtoken",
- "pk": "doc_pulled_from_rfc_queue_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_authors",
    "doc_group_chairs",
    "doc_group_responsible_directors",
@@ -5100,7 +5036,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_ad",
    "doc_affecteddoc_authors",
    "doc_affecteddoc_group_chairs",
@@ -5117,7 +5054,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_notify",
    "stream_managers"
   ],
@@ -5128,7 +5066,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_authors",
    "doc_group_chairs",
    "doc_group_delegates",
@@ -5141,7 +5080,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_affecteddoc_authors",
    "doc_affecteddoc_group_chairs",
    "doc_affecteddoc_notify",
@@ -5159,7 +5099,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "group_mail_list"
   ],
   "desc": "Recipients when the set of approved milestones for a group are edited"
@@ -5169,7 +5110,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iesg_secretary"
   ],
   "desc": "Recipients for message requesting closure of a group"
@@ -5179,7 +5121,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "group_chairs",
    "group_responsible_directors"
   ],
@@ -5190,7 +5133,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "group_chairs",
    "group_changed_personnel",
    "group_responsible_directors",
@@ -5203,7 +5147,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "ipr_submitter"
   ],
   "desc": "Recipients when the secretary follows up on an IPR disclosure submission"
@@ -5213,15 +5158,8 @@
 },
 {
  "fields": {
-  "recipients": [],
-  "desc": "Copied when the secretary follows up on an IPR disclosure submission"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ipr_disclosure_followup_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "ipr_requests"
   ],
   "desc": "Recipients when an IPR disclosure is submitted"
@@ -5231,7 +5169,11 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_ipr_group_or_ad",
+   "ipr_announce"
+  ],
+  "to": [
    "doc_authors"
   ],
   "desc": "Recipients when an IPR disclosure calls out a given document"
@@ -5241,18 +5183,11 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_ipr_group_or_ad",
-   "ipr_announce"
+  "cc": [
+   "ipr_updatedipr_contacts",
+   "ipr_updatedipr_holders"
   ],
-  "desc": "Copied when an IPR disclosure calls out a given document"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ipr_posted_on_doc_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "ipr_submitter"
   ],
   "desc": "Recipients for a message confirming that a disclosure has been posted"
@@ -5262,18 +5197,10 @@
 },
 {
  "fields": {
-  "recipients": [
-   "ipr_updatedipr_contacts",
-   "ipr_updatedipr_holders"
+  "cc": [
+   "iesg_secretary"
   ],
-  "desc": "Copied on a message confirming that a disclosure has been posted"
- },
- "model": "mailtoken.mailtoken",
- "pk": "ipr_posting_confirmation_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "doc_authors",
    "doc_notify",
    "doc_shepherd",
@@ -5286,27 +5213,7 @@
 },
 {
  "fields": {
-  "recipients": [
-   "iesg_secretary"
-  ],
-  "desc": "Copied when a last call has expired"
- },
- "model": "mailtoken.mailtoken",
- "pk": "last_call_expired_cc"
-},
-{
- "fields": {
-  "recipients": [
-   "ietf_announce"
-  ],
-  "desc": "Recipients when a last call is issued"
- },
- "model": "mailtoken.mailtoken",
- "pk": "last_call_issued"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [
    "doc_ad",
    "doc_affecteddoc_authors",
    "doc_affecteddoc_group_chairs",
@@ -5316,14 +5223,18 @@
    "doc_notify",
    "doc_shepherd"
   ],
-  "desc": "Copied when a last call is issued"
+  "to": [
+   "ietf_announce"
+  ],
+  "desc": "Recipients when a last call is issued"
  },
  "model": "mailtoken.mailtoken",
- "pk": "last_call_issued_cc"
+ "pk": "last_call_issued"
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iana_last_call"
   ],
   "desc": "Recipients for IANA message when a last call is issued"
@@ -5333,7 +5244,12 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_ad",
+   "doc_notify",
+   "doc_shepherd"
+  ],
+  "to": [
    "iesg_secretary"
   ],
   "desc": "Recipients when AD requests a last call"
@@ -5343,19 +5259,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_ad",
-   "doc_notify",
-   "doc_shepherd"
-  ],
-  "desc": "Copied when AD requests a last call"
- },
- "model": "mailtoken.mailtoken",
- "pk": "last_call_requested_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "liaison_statements_list"
   ],
   "desc": "Recipients for a message that a pending liaison statement needs approval"
@@ -5365,7 +5270,12 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "liaison_cc",
+   "liaison_response_contact",
+   "liaison_technical_contact"
+  ],
+  "to": [
    "liaison_to_contact"
   ],
   "desc": "Recipients for a message about a liaison statement deadline that is approaching."
@@ -5375,19 +5285,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "liaison_cc",
-   "liaison_response_contact",
-   "liaison_technical_contact"
-  ],
-  "desc": "Copied on a message about a liaison statement deadline that is approaching."
- },
- "model": "mailtoken.mailtoken",
- "pk": "liaison_deadline_soon_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "liaison_manager"
   ],
   "desc": "Recipients for a message requesting an updated list of authorized individuals"
@@ -5397,7 +5296,12 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "liaison_cc",
+   "liaison_response_contact",
+   "liaison_technical_contact"
+  ],
+  "to": [
    "liaison_to_contact"
   ],
   "desc": "Recipient for a message when a new liaison statement is posted"
@@ -5407,19 +5311,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "liaison_cc",
-   "liaison_response_contact",
-   "liaison_technical_contact"
-  ],
-  "desc": "Copied on a message when a new liaison statement is posted"
- },
- "model": "mailtoken.mailtoken",
- "pk": "liaison_statement_posted_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "group_chairs"
   ],
   "desc": "Recipients for reminder message for milestones about to become overdue"
@@ -5429,7 +5322,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "group_chairs"
   ],
   "desc": "Recipients for message about milestones that are overdue"
@@ -5439,7 +5333,10 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "group_chairs"
+  ],
+  "to": [
    "group_responsible_directors"
   ],
   "desc": "Recipients for reminder message that unapproved milestone changes need review"
@@ -5449,17 +5346,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "group_chairs"
-  ],
-  "desc": "Copied on reminder message that unapproved milestone changes need review"
- },
- "model": "mailtoken.mailtoken",
- "pk": "milestone_review_reminder_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "commenter"
   ],
   "desc": "Recipients for a message confirming a comment was made"
@@ -5469,7 +5357,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nominee"
   ],
   "desc": "Recipients for the questionairre that nominees should complete"
@@ -5479,7 +5368,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nominee"
   ],
   "desc": "Recipients for a message reminding a nominee to return a completed questionairre response"
@@ -5489,7 +5379,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nominee"
   ],
   "desc": "Recipeints of message reminding a nominee to accept or decline a nomination"
@@ -5499,7 +5390,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "ietf_secretariat",
    "nomcom_chair"
   ],
@@ -5510,7 +5402,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nominee"
   ],
   "desc": "Recipients the first time a person is nominated for a position, asking them to accept or decline the nomination"
@@ -5520,7 +5413,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nominator"
   ],
   "desc": "Recipients for a message confirming a nomination was made"
@@ -5530,7 +5424,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "nomcom_chair"
   ],
   "desc": "Recipients for a message noting a new nomination has been received"
@@ -5540,7 +5435,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "doc_group_chairs",
+   "doc_notify",
+   "doc_shepherd",
+   "iesg_secretary"
+  ],
+  "to": [
    "doc_ad"
   ],
   "desc": "Recipients when a draft is submitted to the IESG"
@@ -5550,20 +5451,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "doc_group_chairs",
-   "doc_notify",
-   "doc_shepherd",
-   "iesg_secretary"
-  ],
-  "desc": "Copied when a draft is submitted to the IESG"
- },
- "model": "mailtoken.mailtoken",
- "pk": "pubreq_iesg_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "rfc_editor"
   ],
   "desc": "Recipients when a non-IETF stream manager requests publication"
@@ -5573,7 +5462,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "iana_approve"
   ],
   "desc": "Recipients for IANA message when a non-IETF stream manager requests publication"
@@ -5583,7 +5473,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_ad",
    "iesg_secretary"
   ],
@@ -5594,7 +5485,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "internet_draft_requests"
   ],
   "desc": "Recipients of a request to change the state of a draft away from 'Dead'"
@@ -5604,7 +5496,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "group_chairs",
+   "group_mail_list",
+   "group_responsible_directors",
+   "logged_in_person"
+  ],
+  "to": [
    "session_requests"
   ],
   "desc": "Recipients for a normal meeting session request"
@@ -5614,20 +5512,12 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
    "group_chairs",
-   "group_mail_list",
-   "group_responsible_directors",
-   "logged_in_person"
+   "logged_in_person",
+   "session_requests"
   ],
-  "desc": "Copied on a normal meeting session request"
- },
- "model": "mailtoken.mailtoken",
- "pk": "session_requested_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "group_responsible_directors"
   ],
   "desc": "Recipients for a meeting session request for more than 2 sessions"
@@ -5637,19 +5527,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
    "group_chairs",
-   "logged_in_person",
-   "session_requests"
+   "group_mail_list",
+   "group_responsible_directors",
+   "logged_in_person"
   ],
-  "desc": "Copied on a meeting session request for more than 2 sessions"
- },
- "model": "mailtoken.mailtoken",
- "pk": "session_requested_long_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "session_requests"
   ],
   "desc": "Recipients for a message cancelling a session request"
@@ -5659,20 +5543,13 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
    "group_chairs",
    "group_mail_list",
    "group_responsible_directors",
    "logged_in_person"
   ],
-  "desc": "Copied on a message cancelling a session request"
- },
- "model": "mailtoken.mailtoken",
- "pk": "session_request_cancelled_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "session_requests"
   ],
   "desc": "Recipients for a message noting a group plans to not meet"
@@ -5682,20 +5559,11 @@
 },
 {
  "fields": {
-  "recipients": [
-   "group_chairs",
+  "cc": [
    "group_mail_list",
-   "group_responsible_directors",
-   "logged_in_person"
+   "group_responsible_directors"
   ],
-  "desc": "Copied on a message noting a group plans to not meet"
- },
- "model": "mailtoken.mailtoken",
- "pk": "session_request_not_meeting_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "group_chairs"
   ],
   "desc": "Recipients for details when a session has been scheduled"
@@ -5705,18 +5573,10 @@
 },
 {
  "fields": {
-  "recipients": [
-   "group_mail_list",
-   "group_responsible_directors"
+  "cc": [
+   "submission_group_mail_list"
   ],
-  "desc": "Recipients for details when a session has been scheduled"
- },
- "model": "mailtoken.mailtoken",
- "pk": "session_scheduled_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "to": [
    "ietf_announce"
   ],
   "desc": "Recipients for the announcement of a successfully submitted draft"
@@ -5726,17 +5586,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "submission_group_mail_list"
-  ],
-  "desc": "Copied on the announcement of a successfully submitted draft"
- },
- "model": "mailtoken.mailtoken",
- "pk": "sub_announced_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "submission_authors",
    "submission_confirmers"
   ],
@@ -5747,7 +5598,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "submission_group_chairs"
   ],
   "desc": "Recipients for a message requesting group chair approval of a draft submission"
@@ -5757,7 +5609,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "submission_confirmers"
   ],
   "desc": "Recipients for a message requesting confirmation of a draft submission"
@@ -5767,7 +5620,8 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "submission_confirmers"
   ],
   "desc": "Recipients for a message with the full URL for managing a draft submission"
@@ -5777,7 +5631,12 @@
 },
 {
  "fields": {
-  "recipients": [
+  "cc": [
+   "submission_authors",
+   "submission_group_chairs",
+   "submission_submitter"
+  ],
+  "to": [
    "internet_draft_requests"
   ],
   "desc": "Recipients for a manual post request for a draft submission"
@@ -5787,19 +5646,8 @@
 },
 {
  "fields": {
-  "recipients": [
-   "submission_authors",
-   "submission_group_chairs",
-   "submission_submitter"
-  ],
-  "desc": "Copied on a manual post request for a draft submission"
- },
- "model": "mailtoken.mailtoken",
- "pk": "sub_manual_post_requested_cc"
-},
-{
- "fields": {
-  "recipients": [
+  "cc": [],
+  "to": [
    "doc_ad",
    "doc_discussing_ads",
    "doc_notify",
diff --git a/ietf/templates/mailtoken/token.html b/ietf/templates/mailtoken/token.html
index d4a888a86..7cd5a351c 100644
--- a/ietf/templates/mailtoken/token.html
+++ b/ietf/templates/mailtoken/token.html
@@ -20,11 +20,18 @@
     {% for mailtoken in mailtokens %}
         <tr>
           <td><span title="{{mailtoken.desc}}">{{mailtoken.slug}}</span></td>
-          <td>
-            {% for recipient in mailtoken.recipients.all %}
+          <td>To: 
+            {% for recipient in mailtoken.to.all %}
               {% comment %}<span title="{{recipient.desc}}">{{recipient.slug}}</span>{% endcomment %}
               <a href="{% url 'ietf.mailtoken.views.show_recipients' recipient.slug %}" title="{{recipient.desc}}">{{recipient.slug}}</a>{% if not forloop.last %}, {% endif %}
             {% endfor %}
+            {% if mailtoken.cc.exists %}
+              <br/>Cc:
+              {% for recipient in mailtoken.cc.all %}
+                {% comment %}<span title="{{recipient.desc}}">{{recipient.slug}}</span>{% endcomment %}
+                <a href="{% url 'ietf.mailtoken.views.show_recipients' recipient.slug %}" title="{{recipient.desc}}">{{recipient.slug}}</a>{% if not forloop.last %}, {% endif %}
+              {% endfor %}
+            {% endif %}
           </td>
         </tr>
     {% endfor %}