We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Listing CloudFormation stacks should include deleted stacks
Using the AWS API directly returns stacks with a status `DELETE_COMPLETE`; using moto those stacks are not returned.

The existing unit tests actually test for this incorrect behaviour:
https://github.com/spulec/moto/blob/4a275cc/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py#L516-L518

The tests should be updated and the `list_stacks` method on the backend should include the `self.deleted_stacks` data (https://github.com/spulec/moto/blob/4a275cc/moto/cloudformation/models.py#L225-L226)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `moto/cloudformation/models.py`
Content:
```
1 from __future__ import unicode_literals
2 from datetime import datetime
3 import json
4 import yaml
5 import uuid
6 
7 import boto.cloudformation
8 from moto.compat import OrderedDict
9 from moto.core import BaseBackend, BaseModel
10 
11 from .parsing import ResourceMap, OutputMap
12 from .utils import (
13     generate_changeset_id,
14     generate_stack_id,
15     yaml_tag_constructor,
16 )
17 from .exceptions import ValidationError
18 
19 
20 class FakeStack(BaseModel):
21 
22     def __init__(self, stack_id, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, cross_stack_resources=None, create_change_set=False):
23         self.stack_id = stack_id
24         self.name = name
25         self.template = template
26         self._parse_template()
27         self.parameters = parameters
28         self.region_name = region_name
29         self.notification_arns = notification_arns if notification_arns else []
30         self.role_arn = role_arn
31         self.tags = tags if tags else {}
32         self.events = []
33         if create_change_set:
34             self._add_stack_event("REVIEW_IN_PROGRESS",
35                                   resource_status_reason="User Initiated")
36         else:
37             self._add_stack_event("CREATE_IN_PROGRESS",
38                                   resource_status_reason="User Initiated")
39 
40         self.description = self.template_dict.get('Description')
41         self.cross_stack_resources = cross_stack_resources or {}
42         self.resource_map = self._create_resource_map()
43         self.output_map = self._create_output_map()
44         self._add_stack_event("CREATE_COMPLETE")
45         self.status = 'CREATE_COMPLETE'
46 
47     def _create_resource_map(self):
48         resource_map = ResourceMap(
49             self.stack_id, self.name, self.parameters, self.tags, self.region_name, self.template_dict, self.cross_stack_resources)
50         resource_map.create()
51         return resource_map
52 
53     def _create_output_map(self):
54         output_map = OutputMap(self.resource_map, self.template_dict, self.stack_id)
55         output_map.create()
56         return output_map
57 
58     def _add_stack_event(self, resource_status, resource_status_reason=None, resource_properties=None):
59         self.events.append(FakeEvent(
60             stack_id=self.stack_id,
61             stack_name=self.name,
62             logical_resource_id=self.name,
63             physical_resource_id=self.stack_id,
64             resource_type="AWS::CloudFormation::Stack",
65             resource_status=resource_status,
66             resource_status_reason=resource_status_reason,
67             resource_properties=resource_properties,
68         ))
69 
70     def _add_resource_event(self, logical_resource_id, resource_status, resource_status_reason=None, resource_properties=None):
71         # not used yet... feel free to help yourself
72         resource = self.resource_map[logical_resource_id]
73         self.events.append(FakeEvent(
74             stack_id=self.stack_id,
75             stack_name=self.name,
76             logical_resource_id=logical_resource_id,
77             physical_resource_id=resource.physical_resource_id,
78             resource_type=resource.type,
79             resource_status=resource_status,
80             resource_status_reason=resource_status_reason,
81             resource_properties=resource_properties,
82         ))
83 
84     def _parse_template(self):
85         yaml.add_multi_constructor('', yaml_tag_constructor)
86         try:
87             self.template_dict = yaml.load(self.template)
88         except yaml.parser.ParserError:
89             self.template_dict = json.loads(self.template)
90 
91     @property
92     def stack_parameters(self):
93         return self.resource_map.resolved_parameters
94 
95     @property
96     def stack_resources(self):
97         return self.resource_map.values()
98 
99     @property
100     def stack_outputs(self):
101         return self.output_map.values()
102 
103     @property
104     def exports(self):
105         return self.output_map.exports
106 
107     def update(self, template, role_arn=None, parameters=None, tags=None):
108         self._add_stack_event("UPDATE_IN_PROGRESS", resource_status_reason="User Initiated")
109         self.template = template
110         self._parse_template()
111         self.resource_map.update(self.template_dict, parameters)
112         self.output_map = self._create_output_map()
113         self._add_stack_event("UPDATE_COMPLETE")
114         self.status = "UPDATE_COMPLETE"
115         self.role_arn = role_arn
116         # only overwrite tags if passed
117         if tags is not None:
118             self.tags = tags
119             # TODO: update tags in the resource map
120 
121     def delete(self):
122         self._add_stack_event("DELETE_IN_PROGRESS",
123                               resource_status_reason="User Initiated")
124         self.resource_map.delete()
125         self._add_stack_event("DELETE_COMPLETE")
126         self.status = "DELETE_COMPLETE"
127 
128 
129 class FakeEvent(BaseModel):
130 
131     def __init__(self, stack_id, stack_name, logical_resource_id, physical_resource_id, resource_type, resource_status, resource_status_reason=None, resource_properties=None):
132         self.stack_id = stack_id
133         self.stack_name = stack_name
134         self.logical_resource_id = logical_resource_id
135         self.physical_resource_id = physical_resource_id
136         self.resource_type = resource_type
137         self.resource_status = resource_status
138         self.resource_status_reason = resource_status_reason
139         self.resource_properties = resource_properties
140         self.timestamp = datetime.utcnow()
141         self.event_id = uuid.uuid4()
142 
143 
144 class CloudFormationBackend(BaseBackend):
145 
146     def __init__(self):
147         self.stacks = OrderedDict()
148         self.deleted_stacks = {}
149         self.exports = OrderedDict()
150         self.change_sets = OrderedDict()
151 
152     def create_stack(self, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, create_change_set=False):
153         stack_id = generate_stack_id(name)
154         new_stack = FakeStack(
155             stack_id=stack_id,
156             name=name,
157             template=template,
158             parameters=parameters,
159             region_name=region_name,
160             notification_arns=notification_arns,
161             tags=tags,
162             role_arn=role_arn,
163             cross_stack_resources=self.exports,
164             create_change_set=create_change_set,
165         )
166         self.stacks[stack_id] = new_stack
167         self._validate_export_uniqueness(new_stack)
168         for export in new_stack.exports:
169             self.exports[export.name] = export
170         return new_stack
171 
172     def create_change_set(self, stack_name, change_set_name, template, parameters, region_name, change_set_type, notification_arns=None, tags=None, role_arn=None):
173         if change_set_type == 'UPDATE':
174             stacks = self.stacks.values()
175             stack = None
176             for s in stacks:
177                 if s.name == stack_name:
178                     stack = s
179             if stack is None:
180                 raise ValidationError(stack_name)
181 
182         else:
183             stack = self.create_stack(stack_name, template, parameters,
184                                       region_name, notification_arns, tags,
185                                       role_arn, create_change_set=True)
186         change_set_id = generate_changeset_id(change_set_name, region_name)
187         self.stacks[change_set_name] = {'Id': change_set_id,
188                                         'StackId': stack.stack_id}
189         self.change_sets[change_set_id] = stack
190         return change_set_id, stack.stack_id
191 
192     def execute_change_set(self, change_set_name, stack_name=None):
193         stack = None
194         if change_set_name in self.change_sets:
195             # This means arn was passed in
196             stack = self.change_sets[change_set_name]
197         else:
198             for cs in self.change_sets:
199                 if self.change_sets[cs].name == change_set_name:
200                     stack = self.change_sets[cs]
201         if stack is None:
202             raise ValidationError(stack_name)
203         if stack.events[-1].resource_status == 'REVIEW_IN_PROGRESS':
204             stack._add_stack_event('CREATE_COMPLETE')
205         else:
206             stack._add_stack_event('UPDATE_IN_PROGRESS')
207             stack._add_stack_event('UPDATE_COMPLETE')
208         return True
209 
210     def describe_stacks(self, name_or_stack_id):
211         stacks = self.stacks.values()
212         if name_or_stack_id:
213             for stack in stacks:
214                 if stack.name == name_or_stack_id or stack.stack_id == name_or_stack_id:
215                     return [stack]
216             if self.deleted_stacks:
217                 deleted_stacks = self.deleted_stacks.values()
218                 for stack in deleted_stacks:
219                     if stack.stack_id == name_or_stack_id:
220                         return [stack]
221             raise ValidationError(name_or_stack_id)
222         else:
223             return list(stacks)
224 
225     def list_stacks(self):
226         return self.stacks.values()
227 
228     def get_stack(self, name_or_stack_id):
229         all_stacks = dict(self.deleted_stacks, **self.stacks)
230         if name_or_stack_id in all_stacks:
231             # Lookup by stack id - deleted stacks incldued
232             return all_stacks[name_or_stack_id]
233         else:
234             # Lookup by stack name - undeleted stacks only
235             for stack in self.stacks.values():
236                 if stack.name == name_or_stack_id:
237                     return stack
238 
239     def update_stack(self, name, template, role_arn=None, parameters=None, tags=None):
240         stack = self.get_stack(name)
241         stack.update(template, role_arn, parameters=parameters, tags=tags)
242         return stack
243 
244     def list_stack_resources(self, stack_name_or_id):
245         stack = self.get_stack(stack_name_or_id)
246         return stack.stack_resources
247 
248     def delete_stack(self, name_or_stack_id):
249         if name_or_stack_id in self.stacks:
250             # Delete by stack id
251             stack = self.stacks.pop(name_or_stack_id, None)
252             stack.delete()
253             self.deleted_stacks[stack.stack_id] = stack
254             [self.exports.pop(export.name) for export in stack.exports]
255             return self.stacks.pop(name_or_stack_id, None)
256         else:
257             # Delete by stack name
258             for stack in list(self.stacks.values()):
259                 if stack.name == name_or_stack_id:
260                     self.delete_stack(stack.stack_id)
261 
262     def list_exports(self, token):
263         all_exports = list(self.exports.values())
264         if token is None:
265             exports = all_exports[0:100]
266             next_token = '100' if len(all_exports) > 100 else None
267         else:
268             token = int(token)
269             exports = all_exports[token:token + 100]
270             next_token = str(token + 100) if len(all_exports) > token + 100 else None
271         return exports, next_token
272 
273     def _validate_export_uniqueness(self, stack):
274         new_stack_export_names = [x.name for x in stack.exports]
275         export_names = self.exports.keys()
276         if not set(export_names).isdisjoint(new_stack_export_names):
277             raise ValidationError(stack.stack_id, message='Export names must be unique across a given region')
278 
279 
280 cloudformation_backends = {}
281 for region in boto.cloudformation.regions():
282     cloudformation_backends[region.name] = CloudFormationBackend()
283
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py
--- a/moto/cloudformation/models.py
+++ b/moto/cloudformation/models.py
@@ -223,7 +223,11 @@
             return list(stacks)
 
     def list_stacks(self):
-        return self.stacks.values()
+        return [
+            v for v in self.stacks.values()
+        ] + [
+            v for v in self.deleted_stacks.values()
+        ]
 
     def get_stack(self, name_or_stack_id):
         all_stacks = dict(self.deleted_stacks, **self.stacks)

{"golden_diff": "diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py\n--- a/moto/cloudformation/models.py\n+++ b/moto/cloudformation/models.py\n@@ -223,7 +223,11 @@\n             return list(stacks)\n \n     def list_stacks(self):\n-        return self.stacks.values()\n+        return [\n+            v for v in self.stacks.values()\n+        ] + [\n+            v for v in self.deleted_stacks.values()\n+        ]\n \n     def get_stack(self, name_or_stack_id):\n         all_stacks = dict(self.deleted_stacks, **self.stacks)\n", "issue": "Listing CloudFormation stacks should include deleted stacks\nUsing the AWS API directly returns stacks with a status `DELETE_COMPLETE`; using moto those stacks are not returned.\r\n\r\nThe existing unit tests actually test for this incorrect behaviour:\r\nhttps://github.com/spulec/moto/blob/4a275cc/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py#L516-L518\r\n\r\nThe tests should be updated and the `list_stacks` method on the backend should include the `self.deleted_stacks` data (https://github.com/spulec/moto/blob/4a275cc/moto/cloudformation/models.py#L225-L226)\n", "before_files": [{"content": "from __future__ import unicode_literals\nfrom datetime import datetime\nimport json\nimport yaml\nimport uuid\n\nimport boto.cloudformation\nfrom moto.compat import OrderedDict\nfrom moto.core import BaseBackend, BaseModel\n\nfrom .parsing import ResourceMap, OutputMap\nfrom .utils import (\n    generate_changeset_id,\n    generate_stack_id,\n    yaml_tag_constructor,\n)\nfrom .exceptions import ValidationError\n\n\nclass FakeStack(BaseModel):\n\n    def __init__(self, stack_id, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, cross_stack_resources=None, create_change_set=False):\n        self.stack_id = stack_id\n        self.name = name\n        self.template = template\n        self._parse_template()\n        self.parameters = parameters\n        self.region_name = region_name\n        self.notification_arns = notification_arns if notification_arns else []\n        self.role_arn = role_arn\n        self.tags = tags if tags else {}\n        self.events = []\n        if create_change_set:\n            self._add_stack_event(\"REVIEW_IN_PROGRESS\",\n                                  resource_status_reason=\"User Initiated\")\n        else:\n            self._add_stack_event(\"CREATE_IN_PROGRESS\",\n                                  resource_status_reason=\"User Initiated\")\n\n        self.description = self.template_dict.get('Description')\n        self.cross_stack_resources = cross_stack_resources or {}\n        self.resource_map = self._create_resource_map()\n        self.output_map = self._create_output_map()\n        self._add_stack_event(\"CREATE_COMPLETE\")\n        self.status = 'CREATE_COMPLETE'\n\n    def _create_resource_map(self):\n        resource_map = ResourceMap(\n            self.stack_id, self.name, self.parameters, self.tags, self.region_name, self.template_dict, self.cross_stack_resources)\n        resource_map.create()\n        return resource_map\n\n    def _create_output_map(self):\n        output_map = OutputMap(self.resource_map, self.template_dict, self.stack_id)\n        output_map.create()\n        return output_map\n\n    def _add_stack_event(self, resource_status, resource_status_reason=None, resource_properties=None):\n        self.events.append(FakeEvent(\n            stack_id=self.stack_id,\n            stack_name=self.name,\n            logical_resource_id=self.name,\n            physical_resource_id=self.stack_id,\n            resource_type=\"AWS::CloudFormation::Stack\",\n            resource_status=resource_status,\n            resource_status_reason=resource_status_reason,\n            resource_properties=resource_properties,\n        ))\n\n    def _add_resource_event(self, logical_resource_id, resource_status, resource_status_reason=None, resource_properties=None):\n        # not used yet... feel free to help yourself\n        resource = self.resource_map[logical_resource_id]\n        self.events.append(FakeEvent(\n            stack_id=self.stack_id,\n            stack_name=self.name,\n            logical_resource_id=logical_resource_id,\n            physical_resource_id=resource.physical_resource_id,\n            resource_type=resource.type,\n            resource_status=resource_status,\n            resource_status_reason=resource_status_reason,\n            resource_properties=resource_properties,\n        ))\n\n    def _parse_template(self):\n        yaml.add_multi_constructor('', yaml_tag_constructor)\n        try:\n            self.template_dict = yaml.load(self.template)\n        except yaml.parser.ParserError:\n            self.template_dict = json.loads(self.template)\n\n    @property\n    def stack_parameters(self):\n        return self.resource_map.resolved_parameters\n\n    @property\n    def stack_resources(self):\n        return self.resource_map.values()\n\n    @property\n    def stack_outputs(self):\n        return self.output_map.values()\n\n    @property\n    def exports(self):\n        return self.output_map.exports\n\n    def update(self, template, role_arn=None, parameters=None, tags=None):\n        self._add_stack_event(\"UPDATE_IN_PROGRESS\", resource_status_reason=\"User Initiated\")\n        self.template = template\n        self._parse_template()\n        self.resource_map.update(self.template_dict, parameters)\n        self.output_map = self._create_output_map()\n        self._add_stack_event(\"UPDATE_COMPLETE\")\n        self.status = \"UPDATE_COMPLETE\"\n        self.role_arn = role_arn\n        # only overwrite tags if passed\n        if tags is not None:\n            self.tags = tags\n            # TODO: update tags in the resource map\n\n    def delete(self):\n        self._add_stack_event(\"DELETE_IN_PROGRESS\",\n                              resource_status_reason=\"User Initiated\")\n        self.resource_map.delete()\n        self._add_stack_event(\"DELETE_COMPLETE\")\n        self.status = \"DELETE_COMPLETE\"\n\n\nclass FakeEvent(BaseModel):\n\n    def __init__(self, stack_id, stack_name, logical_resource_id, physical_resource_id, resource_type, resource_status, resource_status_reason=None, resource_properties=None):\n        self.stack_id = stack_id\n        self.stack_name = stack_name\n        self.logical_resource_id = logical_resource_id\n        self.physical_resource_id = physical_resource_id\n        self.resource_type = resource_type\n        self.resource_status = resource_status\n        self.resource_status_reason = resource_status_reason\n        self.resource_properties = resource_properties\n        self.timestamp = datetime.utcnow()\n        self.event_id = uuid.uuid4()\n\n\nclass CloudFormationBackend(BaseBackend):\n\n    def __init__(self):\n        self.stacks = OrderedDict()\n        self.deleted_stacks = {}\n        self.exports = OrderedDict()\n        self.change_sets = OrderedDict()\n\n    def create_stack(self, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, create_change_set=False):\n        stack_id = generate_stack_id(name)\n        new_stack = FakeStack(\n            stack_id=stack_id,\n            name=name,\n            template=template,\n            parameters=parameters,\n            region_name=region_name,\n            notification_arns=notification_arns,\n            tags=tags,\n            role_arn=role_arn,\n            cross_stack_resources=self.exports,\n            create_change_set=create_change_set,\n        )\n        self.stacks[stack_id] = new_stack\n        self._validate_export_uniqueness(new_stack)\n        for export in new_stack.exports:\n            self.exports[export.name] = export\n        return new_stack\n\n    def create_change_set(self, stack_name, change_set_name, template, parameters, region_name, change_set_type, notification_arns=None, tags=None, role_arn=None):\n        if change_set_type == 'UPDATE':\n            stacks = self.stacks.values()\n            stack = None\n            for s in stacks:\n                if s.name == stack_name:\n                    stack = s\n            if stack is None:\n                raise ValidationError(stack_name)\n\n        else:\n            stack = self.create_stack(stack_name, template, parameters,\n                                      region_name, notification_arns, tags,\n                                      role_arn, create_change_set=True)\n        change_set_id = generate_changeset_id(change_set_name, region_name)\n        self.stacks[change_set_name] = {'Id': change_set_id,\n                                        'StackId': stack.stack_id}\n        self.change_sets[change_set_id] = stack\n        return change_set_id, stack.stack_id\n\n    def execute_change_set(self, change_set_name, stack_name=None):\n        stack = None\n        if change_set_name in self.change_sets:\n            # This means arn was passed in\n            stack = self.change_sets[change_set_name]\n        else:\n            for cs in self.change_sets:\n                if self.change_sets[cs].name == change_set_name:\n                    stack = self.change_sets[cs]\n        if stack is None:\n            raise ValidationError(stack_name)\n        if stack.events[-1].resource_status == 'REVIEW_IN_PROGRESS':\n            stack._add_stack_event('CREATE_COMPLETE')\n        else:\n            stack._add_stack_event('UPDATE_IN_PROGRESS')\n            stack._add_stack_event('UPDATE_COMPLETE')\n        return True\n\n    def describe_stacks(self, name_or_stack_id):\n        stacks = self.stacks.values()\n        if name_or_stack_id:\n            for stack in stacks:\n                if stack.name == name_or_stack_id or stack.stack_id == name_or_stack_id:\n                    return [stack]\n            if self.deleted_stacks:\n                deleted_stacks = self.deleted_stacks.values()\n                for stack in deleted_stacks:\n                    if stack.stack_id == name_or_stack_id:\n                        return [stack]\n            raise ValidationError(name_or_stack_id)\n        else:\n            return list(stacks)\n\n    def list_stacks(self):\n        return self.stacks.values()\n\n    def get_stack(self, name_or_stack_id):\n        all_stacks = dict(self.deleted_stacks, **self.stacks)\n        if name_or_stack_id in all_stacks:\n            # Lookup by stack id - deleted stacks incldued\n            return all_stacks[name_or_stack_id]\n        else:\n            # Lookup by stack name - undeleted stacks only\n            for stack in self.stacks.values():\n                if stack.name == name_or_stack_id:\n                    return stack\n\n    def update_stack(self, name, template, role_arn=None, parameters=None, tags=None):\n        stack = self.get_stack(name)\n        stack.update(template, role_arn, parameters=parameters, tags=tags)\n        return stack\n\n    def list_stack_resources(self, stack_name_or_id):\n        stack = self.get_stack(stack_name_or_id)\n        return stack.stack_resources\n\n    def delete_stack(self, name_or_stack_id):\n        if name_or_stack_id in self.stacks:\n            # Delete by stack id\n            stack = self.stacks.pop(name_or_stack_id, None)\n            stack.delete()\n            self.deleted_stacks[stack.stack_id] = stack\n            [self.exports.pop(export.name) for export in stack.exports]\n            return self.stacks.pop(name_or_stack_id, None)\n        else:\n            # Delete by stack name\n            for stack in list(self.stacks.values()):\n                if stack.name == name_or_stack_id:\n                    self.delete_stack(stack.stack_id)\n\n    def list_exports(self, token):\n        all_exports = list(self.exports.values())\n        if token is None:\n            exports = all_exports[0:100]\n            next_token = '100' if len(all_exports) > 100 else None\n        else:\n            token = int(token)\n            exports = all_exports[token:token + 100]\n            next_token = str(token + 100) if len(all_exports) > token + 100 else None\n        return exports, next_token\n\n    def _validate_export_uniqueness(self, stack):\n        new_stack_export_names = [x.name for x in stack.exports]\n        export_names = self.exports.keys()\n        if not set(export_names).isdisjoint(new_stack_export_names):\n            raise ValidationError(stack.stack_id, message='Export names must be unique across a given region')\n\n\ncloudformation_backends = {}\nfor region in boto.cloudformation.regions():\n    cloudformation_backends[region.name] = CloudFormationBackend()\n", "path": "moto/cloudformation/models.py"}], "after_files": [{"content": "from __future__ import unicode_literals\nfrom datetime import datetime\nimport json\nimport yaml\nimport uuid\n\nimport boto.cloudformation\nfrom moto.compat import OrderedDict\nfrom moto.core import BaseBackend, BaseModel\n\nfrom .parsing import ResourceMap, OutputMap\nfrom .utils import (\n    generate_changeset_id,\n    generate_stack_id,\n    yaml_tag_constructor,\n)\nfrom .exceptions import ValidationError\n\n\nclass FakeStack(BaseModel):\n\n    def __init__(self, stack_id, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, cross_stack_resources=None, create_change_set=False):\n        self.stack_id = stack_id\n        self.name = name\n        self.template = template\n        self._parse_template()\n        self.parameters = parameters\n        self.region_name = region_name\n        self.notification_arns = notification_arns if notification_arns else []\n        self.role_arn = role_arn\n        self.tags = tags if tags else {}\n        self.events = []\n        if create_change_set:\n            self._add_stack_event(\"REVIEW_IN_PROGRESS\",\n                                  resource_status_reason=\"User Initiated\")\n        else:\n            self._add_stack_event(\"CREATE_IN_PROGRESS\",\n                                  resource_status_reason=\"User Initiated\")\n\n        self.description = self.template_dict.get('Description')\n        self.cross_stack_resources = cross_stack_resources or {}\n        self.resource_map = self._create_resource_map()\n        self.output_map = self._create_output_map()\n        self._add_stack_event(\"CREATE_COMPLETE\")\n        self.status = 'CREATE_COMPLETE'\n\n    def _create_resource_map(self):\n        resource_map = ResourceMap(\n            self.stack_id, self.name, self.parameters, self.tags, self.region_name, self.template_dict, self.cross_stack_resources)\n        resource_map.create()\n        return resource_map\n\n    def _create_output_map(self):\n        output_map = OutputMap(self.resource_map, self.template_dict, self.stack_id)\n        output_map.create()\n        return output_map\n\n    def _add_stack_event(self, resource_status, resource_status_reason=None, resource_properties=None):\n        self.events.append(FakeEvent(\n            stack_id=self.stack_id,\n            stack_name=self.name,\n            logical_resource_id=self.name,\n            physical_resource_id=self.stack_id,\n            resource_type=\"AWS::CloudFormation::Stack\",\n            resource_status=resource_status,\n            resource_status_reason=resource_status_reason,\n            resource_properties=resource_properties,\n        ))\n\n    def _add_resource_event(self, logical_resource_id, resource_status, resource_status_reason=None, resource_properties=None):\n        # not used yet... feel free to help yourself\n        resource = self.resource_map[logical_resource_id]\n        self.events.append(FakeEvent(\n            stack_id=self.stack_id,\n            stack_name=self.name,\n            logical_resource_id=logical_resource_id,\n            physical_resource_id=resource.physical_resource_id,\n            resource_type=resource.type,\n            resource_status=resource_status,\n            resource_status_reason=resource_status_reason,\n            resource_properties=resource_properties,\n        ))\n\n    def _parse_template(self):\n        yaml.add_multi_constructor('', yaml_tag_constructor)\n        try:\n            self.template_dict = yaml.load(self.template)\n        except yaml.parser.ParserError:\n            self.template_dict = json.loads(self.template)\n\n    @property\n    def stack_parameters(self):\n        return self.resource_map.resolved_parameters\n\n    @property\n    def stack_resources(self):\n        return self.resource_map.values()\n\n    @property\n    def stack_outputs(self):\n        return self.output_map.values()\n\n    @property\n    def exports(self):\n        return self.output_map.exports\n\n    def update(self, template, role_arn=None, parameters=None, tags=None):\n        self._add_stack_event(\"UPDATE_IN_PROGRESS\", resource_status_reason=\"User Initiated\")\n        self.template = template\n        self._parse_template()\n        self.resource_map.update(self.template_dict, parameters)\n        self.output_map = self._create_output_map()\n        self._add_stack_event(\"UPDATE_COMPLETE\")\n        self.status = \"UPDATE_COMPLETE\"\n        self.role_arn = role_arn\n        # only overwrite tags if passed\n        if tags is not None:\n            self.tags = tags\n            # TODO: update tags in the resource map\n\n    def delete(self):\n        self._add_stack_event(\"DELETE_IN_PROGRESS\",\n                              resource_status_reason=\"User Initiated\")\n        self.resource_map.delete()\n        self._add_stack_event(\"DELETE_COMPLETE\")\n        self.status = \"DELETE_COMPLETE\"\n\n\nclass FakeEvent(BaseModel):\n\n    def __init__(self, stack_id, stack_name, logical_resource_id, physical_resource_id, resource_type, resource_status, resource_status_reason=None, resource_properties=None):\n        self.stack_id = stack_id\n        self.stack_name = stack_name\n        self.logical_resource_id = logical_resource_id\n        self.physical_resource_id = physical_resource_id\n        self.resource_type = resource_type\n        self.resource_status = resource_status\n        self.resource_status_reason = resource_status_reason\n        self.resource_properties = resource_properties\n        self.timestamp = datetime.utcnow()\n        self.event_id = uuid.uuid4()\n\n\nclass CloudFormationBackend(BaseBackend):\n\n    def __init__(self):\n        self.stacks = OrderedDict()\n        self.deleted_stacks = {}\n        self.exports = OrderedDict()\n        self.change_sets = OrderedDict()\n\n    def create_stack(self, name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, create_change_set=False):\n        stack_id = generate_stack_id(name)\n        new_stack = FakeStack(\n            stack_id=stack_id,\n            name=name,\n            template=template,\n            parameters=parameters,\n            region_name=region_name,\n            notification_arns=notification_arns,\n            tags=tags,\n            role_arn=role_arn,\n            cross_stack_resources=self.exports,\n            create_change_set=create_change_set,\n        )\n        self.stacks[stack_id] = new_stack\n        self._validate_export_uniqueness(new_stack)\n        for export in new_stack.exports:\n            self.exports[export.name] = export\n        return new_stack\n\n    def create_change_set(self, stack_name, change_set_name, template, parameters, region_name, change_set_type, notification_arns=None, tags=None, role_arn=None):\n        if change_set_type == 'UPDATE':\n            stacks = self.stacks.values()\n            stack = None\n            for s in stacks:\n                if s.name == stack_name:\n                    stack = s\n            if stack is None:\n                raise ValidationError(stack_name)\n\n        else:\n            stack = self.create_stack(stack_name, template, parameters,\n                                      region_name, notification_arns, tags,\n                                      role_arn, create_change_set=True)\n        change_set_id = generate_changeset_id(change_set_name, region_name)\n        self.stacks[change_set_name] = {'Id': change_set_id,\n                                        'StackId': stack.stack_id}\n        self.change_sets[change_set_id] = stack\n        return change_set_id, stack.stack_id\n\n    def execute_change_set(self, change_set_name, stack_name=None):\n        stack = None\n        if change_set_name in self.change_sets:\n            # This means arn was passed in\n            stack = self.change_sets[change_set_name]\n        else:\n            for cs in self.change_sets:\n                if self.change_sets[cs].name == change_set_name:\n                    stack = self.change_sets[cs]\n        if stack is None:\n            raise ValidationError(stack_name)\n        if stack.events[-1].resource_status == 'REVIEW_IN_PROGRESS':\n            stack._add_stack_event('CREATE_COMPLETE')\n        else:\n            stack._add_stack_event('UPDATE_IN_PROGRESS')\n            stack._add_stack_event('UPDATE_COMPLETE')\n        return True\n\n    def describe_stacks(self, name_or_stack_id):\n        stacks = self.stacks.values()\n        if name_or_stack_id:\n            for stack in stacks:\n                if stack.name == name_or_stack_id or stack.stack_id == name_or_stack_id:\n                    return [stack]\n            if self.deleted_stacks:\n                deleted_stacks = self.deleted_stacks.values()\n                for stack in deleted_stacks:\n                    if stack.stack_id == name_or_stack_id:\n                        return [stack]\n            raise ValidationError(name_or_stack_id)\n        else:\n            return list(stacks)\n\n    def list_stacks(self):\n        return [\n            v for v in self.stacks.values()\n        ] + [\n            v for v in self.deleted_stacks.values()\n        ]\n\n    def get_stack(self, name_or_stack_id):\n        all_stacks = dict(self.deleted_stacks, **self.stacks)\n        if name_or_stack_id in all_stacks:\n            # Lookup by stack id - deleted stacks incldued\n            return all_stacks[name_or_stack_id]\n        else:\n            # Lookup by stack name - undeleted stacks only\n            for stack in self.stacks.values():\n                if stack.name == name_or_stack_id:\n                    return stack\n\n    def update_stack(self, name, template, role_arn=None, parameters=None, tags=None):\n        stack = self.get_stack(name)\n        stack.update(template, role_arn, parameters=parameters, tags=tags)\n        return stack\n\n    def list_stack_resources(self, stack_name_or_id):\n        stack = self.get_stack(stack_name_or_id)\n        return stack.stack_resources\n\n    def delete_stack(self, name_or_stack_id):\n        if name_or_stack_id in self.stacks:\n            # Delete by stack id\n            stack = self.stacks.pop(name_or_stack_id, None)\n            stack.delete()\n            self.deleted_stacks[stack.stack_id] = stack\n            [self.exports.pop(export.name) for export in stack.exports]\n            return self.stacks.pop(name_or_stack_id, None)\n        else:\n            # Delete by stack name\n            for stack in list(self.stacks.values()):\n                if stack.name == name_or_stack_id:\n                    self.delete_stack(stack.stack_id)\n\n    def list_exports(self, token):\n        all_exports = list(self.exports.values())\n        if token is None:\n            exports = all_exports[0:100]\n            next_token = '100' if len(all_exports) > 100 else None\n        else:\n            token = int(token)\n            exports = all_exports[token:token + 100]\n            next_token = str(token + 100) if len(all_exports) > token + 100 else None\n        return exports, next_token\n\n    def _validate_export_uniqueness(self, stack):\n        new_stack_export_names = [x.name for x in stack.exports]\n        export_names = self.exports.keys()\n        if not set(export_names).isdisjoint(new_stack_export_names):\n            raise ValidationError(stack.stack_id, message='Export names must be unique across a given region')\n\n\ncloudformation_backends = {}\nfor region in boto.cloudformation.regions():\n    cloudformation_backends[region.name] = CloudFormationBackend()\n", "path": "moto/cloudformation/models.py"}]}