diff --git a/Lib/plistlib.py b/Lib/plistlib.py
new file mode 100644
index 0000000..db5eea1
--- /dev/null
+++ b/Lib/plistlib.py
@@ -0,0 +1,469 @@
+"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
+
+The PropertList (.plist) file format is a simple XML pickle supporting
+basic object types, like dictionaries, lists, numbers and strings.
+Usually the top level object is a dictionary.
+
+To write out a plist file, use the writePlist(rootObject, pathOrFile)
+function. 'rootObject' is the top level object, 'pathOrFile' is a
+filename or a (writable) file object.
+
+To parse a plist from a file, use the readPlist(pathOrFile) function,
+with a file name or a (readable) file object as the only argument. It
+returns the top level object (again, usually a dictionary).
+
+To work with plist data in bytes objects, you can use readPlistFromBytes()
+and writePlistToBytes().
+
+Values can be strings, integers, floats, booleans, tuples, lists,
+dictionaries, Data or datetime.datetime objects. String values (including
+dictionary keys) may be unicode strings -- they will be written out as
+UTF-8.
+
+The <data> plist type is supported through the Data class. This is a
+thin wrapper around a Python bytes object.
+
+Generate Plist example:
+
+    pl = dict(
+        aString="Doodah",
+        aList=["A", "B", 12, 32.1, [1, 2, 3]],
+        aFloat = 0.1,
+        anInt = 728,
+        aDict=dict(
+            anotherString="<hello & hi there!>",
+            aUnicodeValue=u'M\xe4ssig, Ma\xdf',
+            aTrueValue=True,
+            aFalseValue=False,
+        ),
+        someData = Data(b"<binary gunk>"),
+        someMoreData = Data(b"<lots of binary gunk>" * 10),
+        aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
+    )
+    # unicode keys are possible, but a little awkward to use:
+    pl[u'\xc5benraa'] = "That was a unicode key."
+    writePlist(pl, fileName)
+
+Parse Plist example:
+
+    pl = readPlist(pathOrFile)
+    print pl["aKey"]
+"""
+
+
+__all__ = [
+    "readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes",
+    "readPlistFromResource", "writePlistToResource",
+    "Plist", "Data", "Dict"
+]
+# Note: the Plist and Dict classes have been deprecated.
+
+import binascii
+import datetime
+from io import BytesIO
+import re
+
+
+def readPlist(pathOrFile):
+    """Read a .plist file. 'pathOrFile' may either be a file name or a
+    (readable) file object. Return the unpacked root object (which
+    usually is a dictionary).
+    """
+    didOpen = False
+    if isinstance(pathOrFile, str):
+        pathOrFile = open(pathOrFile, 'rb')
+        didOpen = True
+    p = PlistParser()
+    rootObject = p.parse(pathOrFile)
+    if didOpen:
+        pathOrFile.close()
+    return rootObject
+
+
+def writePlist(rootObject, pathOrFile):
+    """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a
+    file name or a (writable) file object.
+    """
+    didOpen = False
+    if isinstance(pathOrFile, str):
+        pathOrFile = open(pathOrFile, 'wb')
+        didOpen = True
+    writer = PlistWriter(pathOrFile)
+    writer.writeln("<plist version=\"1.0\">")
+    writer.writeValue(rootObject)
+    writer.writeln("</plist>")
+    if didOpen:
+        pathOrFile.close()
+
+
+def readPlistFromBytes(data):
+    """Read a plist data from a bytes object. Return the root object.
+    """
+    return readPlist(BytesIO(data))
+
+
+def writePlistToBytes(rootObject):
+    """Return 'rootObject' as a plist-formatted bytes object.
+    """
+    f = BytesIO()
+    writePlist(rootObject, f)
+    return f.getvalue()
+
+
+def readPlistFromResource(path, restype='plst', resid=0):
+    """Read plst resource from the resource fork of path.
+    """
+    from Carbon.File import FSRef, FSGetResourceForkName
+    from Carbon.Files import fsRdPerm
+    from Carbon import Res
+    fsRef = FSRef(path)
+    resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm)
+    Res.UseResFile(resNum)
+    plistData = Res.Get1Resource(restype, resid).data
+    Res.CloseResFile(resNum)
+    return readPlistFromString(plistData)
+
+
+def writePlistToResource(rootObject, path, restype='plst', resid=0):
+    """Write 'rootObject' as a plst resource to the resource fork of path.
+    """
+    from Carbon.File import FSRef, FSGetResourceForkName
+    from Carbon.Files import fsRdWrPerm
+    from Carbon import Res
+    plistData = writePlistToString(rootObject)
+    fsRef = FSRef(path)
+    resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm)
+    Res.UseResFile(resNum)
+    try:
+        Res.Get1Resource(restype, resid).RemoveResource()
+    except Res.Error:
+        pass
+    res = Res.Resource(plistData)
+    res.AddResource(restype, resid, '')
+    res.WriteResource()
+    Res.CloseResFile(resNum)
+
+
+class DumbXMLWriter:
+    def __init__(self, file, indentLevel=0, indent="\t"):
+        self.file = file
+        self.stack = []
+        self.indentLevel = indentLevel
+        self.indent = indent
+
+    def beginElement(self, element):
+        self.stack.append(element)
+        self.writeln("<%s>" % element)
+        self.indentLevel += 1
+
+    def endElement(self, element):
+        assert self.indentLevel > 0
+        assert self.stack.pop() == element
+        self.indentLevel -= 1
+        self.writeln("</%s>" % element)
+
+    def simpleElement(self, element, value=None):
+        if value is not None:
+            value = _escape(value)
+            self.writeln("<%s>%s</%s>" % (element, value, element))
+        else:
+            self.writeln("<%s/>" % element)
+
+    def writeln(self, line):
+        if line:
+            # plist has fixed encoding of utf-8
+            if isinstance(line, str):
+                line = line.encode('utf-8')
+            self.file.write(self.indentLevel * self.indent)
+            self.file.write(line)
+        self.file.write(b'\n')
+
+
+# Contents should conform to a subset of ISO 8601
+# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with
+#  a loss of precision)
+_dateParser = re.compile(r"(?P<year>\d\d\d\d)(?:-(?P<month>\d\d)(?:-(?P<day>\d\d)(?:T(?P<hour>\d\d)(?::(?P<minute>\d\d)(?::(?P<second>\d\d))?)?)?)?)?Z")
+
+def _dateFromString(s):
+    order = ('year', 'month', 'day', 'hour', 'minute', 'second')
+    gd = _dateParser.match(s).groupdict()
+    lst = []
+    for key in order:
+        val = gd[key]
+        if val is None:
+            break
+        lst.append(int(val))
+    return datetime.datetime(*lst)
+
+def _dateToString(d):
+    return '%04d-%02d-%02dT%02d:%02d:%02dZ' % (
+        d.year, d.month, d.day,
+        d.hour, d.minute, d.second
+    )
+
+
+# Regex to find any control chars, except for \t \n and \r
+_controlCharPat = re.compile(
+    r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f"
+    r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]")
+
+def _escape(text):
+    m = _controlCharPat.search(text)
+    if m is not None:
+        raise ValueError("strings can't contains control characters; "
+                         "use plistlib.Data instead")
+    text = text.replace("\r\n", "\n")       # convert DOS line endings
+    text = text.replace("\r", "\n")         # convert Mac line endings
+    text = text.replace("&", "&amp;")       # escape '&'
+    text = text.replace("<", "&lt;")        # escape '<'
+    text = text.replace(">", "&gt;")        # escape '>'
+    return text
+
+
+PLISTHEADER = b"""\
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+"""
+
+class PlistWriter(DumbXMLWriter):
+
+    def __init__(self, file, indentLevel=0, indent=b"\t", writeHeader=1):
+        if writeHeader:
+            file.write(PLISTHEADER)
+        DumbXMLWriter.__init__(self, file, indentLevel, indent)
+
+    def writeValue(self, value):
+        if isinstance(value, str):
+            self.simpleElement("string", value)
+        elif isinstance(value, bool):
+            # must switch for bool before int, as bool is a
+            # subclass of int...
+            if value:
+                self.simpleElement("true")
+            else:
+                self.simpleElement("false")
+        elif isinstance(value, int):
+            self.simpleElement("integer", "%d" % value)
+        elif isinstance(value, float):
+            self.simpleElement("real", repr(value))
+        elif isinstance(value, dict):
+            self.writeDict(value)
+        elif isinstance(value, Data):
+            self.writeData(value)
+        elif isinstance(value, datetime.datetime):
+            self.simpleElement("date", _dateToString(value))
+        elif isinstance(value, (tuple, list)):
+            self.writeArray(value)
+        else:
+            raise TypeError("unsuported type: %s" % type(value))
+
+    def writeData(self, data):
+        self.beginElement("data")
+        self.indentLevel -= 1
+        maxlinelength = 76 - len(self.indent.replace(b"\t", b" " * 8) *
+                                 self.indentLevel)
+        for line in data.asBase64(maxlinelength).split(b"\n"):
+            if line:
+                self.writeln(line)
+        self.indentLevel += 1
+        self.endElement("data")
+
+    def writeDict(self, d):
+        self.beginElement("dict")
+        items = sorted(d.items())
+        for key, value in items:
+            if not isinstance(key, str):
+                raise TypeError("keys must be strings")
+            self.simpleElement("key", key)
+            self.writeValue(value)
+        self.endElement("dict")
+
+    def writeArray(self, array):
+        self.beginElement("array")
+        for value in array:
+            self.writeValue(value)
+        self.endElement("array")
+
+
+class _InternalDict(dict):
+
+    # This class is needed while Dict is scheduled for deprecation:
+    # we only need to warn when a *user* instantiates Dict or when
+    # the "attribute notation for dict keys" is used.
+
+    def __getattr__(self, attr):
+        try:
+            value = self[attr]
+        except KeyError:
+            raise AttributeError(attr)
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+        return value
+
+    def __setattr__(self, attr, value):
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+        self[attr] = value
+
+    def __delattr__(self, attr):
+        try:
+            del self[attr]
+        except KeyError:
+            raise AttributeError(attr)
+        from warnings import warn
+        warn("Attribute access from plist dicts is deprecated, use d[key] "
+             "notation instead", PendingDeprecationWarning)
+
+class Dict(_InternalDict):
+
+    def __init__(self, **kwargs):
+        from warnings import warn
+        warn("The plistlib.Dict class is deprecated, use builtin dict instead",
+             PendingDeprecationWarning)
+        super().__init__(**kwargs)
+
+
+class Plist(_InternalDict):
+
+    """This class has been deprecated. Use readPlist() and writePlist()
+    functions instead, together with regular dict objects.
+    """
+
+    def __init__(self, **kwargs):
+        from warnings import warn
+        warn("The Plist class is deprecated, use the readPlist() and "
+             "writePlist() functions instead", PendingDeprecationWarning)
+        super().__init__(**kwargs)
+
+    def fromFile(cls, pathOrFile):
+        """Deprecated. Use the readPlist() function instead."""
+        rootObject = readPlist(pathOrFile)
+        plist = cls()
+        plist.update(rootObject)
+        return plist
+    fromFile = classmethod(fromFile)
+
+    def write(self, pathOrFile):
+        """Deprecated. Use the writePlist() function instead."""
+        writePlist(self, pathOrFile)
+
+
+def _encodeBase64(s, maxlinelength=76):
+    # copied from base64.encodestring(), with added maxlinelength argument
+    maxbinsize = (maxlinelength//4)*3
+    pieces = []
+    for i in range(0, len(s), maxbinsize):
+        chunk = s[i : i + maxbinsize]
+        pieces.append(binascii.b2a_base64(chunk))
+    return b''.join(pieces)
+
+class Data:
+
+    """Wrapper for binary data."""
+
+    def __init__(self, data):
+        if not isinstance(data, bytes):
+            raise TypeError("data must be as bytes")
+        self.data = data
+
+    @classmethod
+    def fromBase64(cls, data):
+        # base64.decodestring just calls binascii.a2b_base64;
+        # it seems overkill to use both base64 and binascii.
+        return cls(binascii.a2b_base64(data))
+
+    def asBase64(self, maxlinelength=76):
+        return _encodeBase64(self.data, maxlinelength)
+
+    def __eq__(self, other):
+        if isinstance(other, self.__class__):
+            return self.data == other.data
+        elif isinstance(other, str):
+            return self.data == other
+        else:
+            return id(self) == id(other)
+
+    def __repr__(self):
+        return "%s(%s)" % (self.__class__.__name__, repr(self.data))
+
+
+class PlistParser:
+
+    def __init__(self):
+        self.stack = []
+        self.currentKey = None
+        self.root = None
+
+    def parse(self, fileobj):
+        from xml.parsers.expat import ParserCreate
+        parser = ParserCreate()
+        parser.StartElementHandler = self.handleBeginElement
+        parser.EndElementHandler = self.handleEndElement
+        parser.CharacterDataHandler = self.handleData
+        parser.ParseFile(fileobj)
+        return self.root
+
+    def handleBeginElement(self, element, attrs):
+        self.data = []
+        handler = getattr(self, "begin_" + element, None)
+        if handler is not None:
+            handler(attrs)
+
+    def handleEndElement(self, element):
+        handler = getattr(self, "end_" + element, None)
+        if handler is not None:
+            handler()
+
+    def handleData(self, data):
+        self.data.append(data)
+
+    def addObject(self, value):
+        if self.currentKey is not None:
+            self.stack[-1][self.currentKey] = value
+            self.currentKey = None
+        elif not self.stack:
+            # this is the root object
+            self.root = value
+        else:
+            self.stack[-1].append(value)
+
+    def getData(self):
+        data = ''.join(self.data)
+        self.data = []
+        return data
+
+    # element handlers
+
+    def begin_dict(self, attrs):
+        d = _InternalDict()
+        self.addObject(d)
+        self.stack.append(d)
+    def end_dict(self):
+        self.stack.pop()
+
+    def end_key(self):
+        self.currentKey = self.getData()
+
+    def begin_array(self, attrs):
+        a = []
+        self.addObject(a)
+        self.stack.append(a)
+    def end_array(self):
+        self.stack.pop()
+
+    def end_true(self):
+        self.addObject(True)
+    def end_false(self):
+        self.addObject(False)
+    def end_integer(self):
+        self.addObject(int(self.getData()))
+    def end_real(self):
+        self.addObject(float(self.getData()))
+    def end_string(self):
+        self.addObject(self.getData())
+    def end_data(self):
+        self.addObject(Data.fromBase64(self.getData().encode("utf-8")))
+    def end_date(self):
+        self.addObject(_dateFromString(self.getData()))
