bug 1413336 - (1/7) update pyasn1 to 0.3.7 r?ted draft
authorDavid Keeler <dkeeler@mozilla.com>
Fri, 03 Nov 2017 16:53:21 -0700
changeset 699145 bcb0c496ad15eef2e821450660376c570c02ffe9
parent 699096 a3f183201f7f183c263d554bfb15fbf0b0ed2ea4
child 699146 0369c1eca34f1061c80e1148c867972b629fa23d
push id89479
push userbmo:dkeeler@mozilla.com
push dateThu, 16 Nov 2017 18:28:32 +0000
reviewersted
bugs1413336
milestone59.0a1
bug 1413336 - (1/7) update pyasn1 to 0.3.7 r?ted MozReview-Commit-ID: L3bvhOZRQyN
third_party/python/pyasn1/CHANGES
third_party/python/pyasn1/CHANGES.rst
third_party/python/pyasn1/LICENSE
third_party/python/pyasn1/LICENSE.rst
third_party/python/pyasn1/MANIFEST.in
third_party/python/pyasn1/PKG-INFO
third_party/python/pyasn1/README
third_party/python/pyasn1/README.md
third_party/python/pyasn1/THANKS
third_party/python/pyasn1/TODO
third_party/python/pyasn1/TODO.rst
third_party/python/pyasn1/doc/Makefile
third_party/python/pyasn1/doc/codecs.html
third_party/python/pyasn1/doc/constraints.html
third_party/python/pyasn1/doc/constructed.html
third_party/python/pyasn1/doc/intro.html
third_party/python/pyasn1/doc/pyasn1-tutorial.html
third_party/python/pyasn1/doc/scalar.html
third_party/python/pyasn1/doc/source/changelog.rst
third_party/python/pyasn1/doc/source/conf.py
third_party/python/pyasn1/doc/source/contents.rst
third_party/python/pyasn1/doc/source/docs/api-reference.rst
third_party/python/pyasn1/doc/source/docs/codec/ber/contents.rst
third_party/python/pyasn1/doc/source/docs/codec/cer/contents.rst
third_party/python/pyasn1/doc/source/docs/codec/der/contents.rst
third_party/python/pyasn1/doc/source/docs/codec/native/contents.rst
third_party/python/pyasn1/doc/source/docs/tutorial.rst
third_party/python/pyasn1/doc/source/docs/type/char/bmpstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/contents.rst
third_party/python/pyasn1/doc/source/docs/type/char/generalstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/graphicstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/ia5string.rst
third_party/python/pyasn1/doc/source/docs/type/char/iso646string.rst
third_party/python/pyasn1/doc/source/docs/type/char/numericstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/printablestring.rst
third_party/python/pyasn1/doc/source/docs/type/char/t61string.rst
third_party/python/pyasn1/doc/source/docs/type/char/teletexstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/universalstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/utf8string.rst
third_party/python/pyasn1/doc/source/docs/type/char/videotexstring.rst
third_party/python/pyasn1/doc/source/docs/type/char/visiblestring.rst
third_party/python/pyasn1/doc/source/docs/type/namedtype/contents.rst
third_party/python/pyasn1/doc/source/docs/type/namedtype/defaultednamedtype.rst
third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtype.rst
third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtypes.rst
third_party/python/pyasn1/doc/source/docs/type/namedtype/optionalnamedtype.rst
third_party/python/pyasn1/doc/source/docs/type/namedval/contents.rst
third_party/python/pyasn1/doc/source/docs/type/namedval/namedval.rst
third_party/python/pyasn1/doc/source/docs/type/tag/contents.rst
third_party/python/pyasn1/doc/source/docs/type/tag/tag.rst
third_party/python/pyasn1/doc/source/docs/type/tag/tagmap.rst
third_party/python/pyasn1/doc/source/docs/type/tag/tagset.rst
third_party/python/pyasn1/doc/source/docs/type/univ/any.rst
third_party/python/pyasn1/doc/source/docs/type/univ/bitstring.rst
third_party/python/pyasn1/doc/source/docs/type/univ/boolean.rst
third_party/python/pyasn1/doc/source/docs/type/univ/choice.rst
third_party/python/pyasn1/doc/source/docs/type/univ/contents.rst
third_party/python/pyasn1/doc/source/docs/type/univ/enumerated.rst
third_party/python/pyasn1/doc/source/docs/type/univ/integer.rst
third_party/python/pyasn1/doc/source/docs/type/univ/null.rst
third_party/python/pyasn1/doc/source/docs/type/univ/objectidentifier.rst
third_party/python/pyasn1/doc/source/docs/type/univ/octetstring.rst
third_party/python/pyasn1/doc/source/docs/type/univ/real.rst
third_party/python/pyasn1/doc/source/docs/type/univ/sequence.rst
third_party/python/pyasn1/doc/source/docs/type/univ/sequenceof.rst
third_party/python/pyasn1/doc/source/docs/type/univ/set.rst
third_party/python/pyasn1/doc/source/docs/type/univ/setof.rst
third_party/python/pyasn1/doc/source/docs/type/useful/contents.rst
third_party/python/pyasn1/doc/source/docs/type/useful/generalizedtime.rst
third_party/python/pyasn1/doc/source/docs/type/useful/objectdescriptor.rst
third_party/python/pyasn1/doc/source/docs/type/useful/utctime.rst
third_party/python/pyasn1/doc/source/example-use-case.rst
third_party/python/pyasn1/doc/source/license.rst
third_party/python/pyasn1/doc/tagging.html
third_party/python/pyasn1/pyasn1.egg-info/PKG-INFO
third_party/python/pyasn1/pyasn1.egg-info/SOURCES.txt
third_party/python/pyasn1/pyasn1/__init__.py
third_party/python/pyasn1/pyasn1/codec/ber/decoder.py
third_party/python/pyasn1/pyasn1/codec/ber/encoder.py
third_party/python/pyasn1/pyasn1/codec/ber/eoo.py
third_party/python/pyasn1/pyasn1/codec/cer/decoder.py
third_party/python/pyasn1/pyasn1/codec/cer/encoder.py
third_party/python/pyasn1/pyasn1/codec/der/decoder.py
third_party/python/pyasn1/pyasn1/codec/der/encoder.py
third_party/python/pyasn1/pyasn1/codec/native/__init__.py
third_party/python/pyasn1/pyasn1/codec/native/decoder.py
third_party/python/pyasn1/pyasn1/codec/native/encoder.py
third_party/python/pyasn1/pyasn1/compat/binary.py
third_party/python/pyasn1/pyasn1/compat/calling.py
third_party/python/pyasn1/pyasn1/compat/dateandtime.py
third_party/python/pyasn1/pyasn1/compat/integer.py
third_party/python/pyasn1/pyasn1/compat/octets.py
third_party/python/pyasn1/pyasn1/compat/string.py
third_party/python/pyasn1/pyasn1/debug.py
third_party/python/pyasn1/pyasn1/error.py
third_party/python/pyasn1/pyasn1/type/base.py
third_party/python/pyasn1/pyasn1/type/char.py
third_party/python/pyasn1/pyasn1/type/constraint.py
third_party/python/pyasn1/pyasn1/type/error.py
third_party/python/pyasn1/pyasn1/type/namedtype.py
third_party/python/pyasn1/pyasn1/type/namedval.py
third_party/python/pyasn1/pyasn1/type/tag.py
third_party/python/pyasn1/pyasn1/type/tagmap.py
third_party/python/pyasn1/pyasn1/type/univ.py
third_party/python/pyasn1/pyasn1/type/useful.py
third_party/python/pyasn1/setup.cfg
third_party/python/pyasn1/setup.py
third_party/python/pyasn1/test/__init__.py
third_party/python/pyasn1/test/codec/__init__.py
third_party/python/pyasn1/test/codec/ber/__init__.py
third_party/python/pyasn1/test/codec/ber/suite.py
third_party/python/pyasn1/test/codec/ber/test_decoder.py
third_party/python/pyasn1/test/codec/ber/test_encoder.py
third_party/python/pyasn1/test/codec/cer/__init__.py
third_party/python/pyasn1/test/codec/cer/suite.py
third_party/python/pyasn1/test/codec/cer/test_decoder.py
third_party/python/pyasn1/test/codec/cer/test_encoder.py
third_party/python/pyasn1/test/codec/der/__init__.py
third_party/python/pyasn1/test/codec/der/suite.py
third_party/python/pyasn1/test/codec/der/test_decoder.py
third_party/python/pyasn1/test/codec/der/test_encoder.py
third_party/python/pyasn1/test/codec/suite.py
third_party/python/pyasn1/test/suite.py
third_party/python/pyasn1/test/type/__init__.py
third_party/python/pyasn1/test/type/suite.py
third_party/python/pyasn1/test/type/test_constraint.py
third_party/python/pyasn1/test/type/test_namedtype.py
third_party/python/pyasn1/test/type/test_tag.py
third_party/python/pyasn1/test/type/test_univ.py
third_party/python/pyasn1/tests/__init__.py
third_party/python/pyasn1/tests/__main__.py
third_party/python/pyasn1/tests/base.py
third_party/python/pyasn1/tests/codec/__init__.py
third_party/python/pyasn1/tests/codec/__main__.py
third_party/python/pyasn1/tests/codec/ber/__init__.py
third_party/python/pyasn1/tests/codec/ber/__main__.py
third_party/python/pyasn1/tests/codec/ber/test_decoder.py
third_party/python/pyasn1/tests/codec/ber/test_encoder.py
third_party/python/pyasn1/tests/codec/cer/__init__.py
third_party/python/pyasn1/tests/codec/cer/__main__.py
third_party/python/pyasn1/tests/codec/cer/test_decoder.py
third_party/python/pyasn1/tests/codec/cer/test_encoder.py
third_party/python/pyasn1/tests/codec/der/__init__.py
third_party/python/pyasn1/tests/codec/der/__main__.py
third_party/python/pyasn1/tests/codec/der/test_decoder.py
third_party/python/pyasn1/tests/codec/der/test_encoder.py
third_party/python/pyasn1/tests/codec/native/__init__.py
third_party/python/pyasn1/tests/codec/native/__main__.py
third_party/python/pyasn1/tests/codec/native/test_decoder.py
third_party/python/pyasn1/tests/codec/native/test_encoder.py
third_party/python/pyasn1/tests/compat/__init__.py
third_party/python/pyasn1/tests/compat/__main__.py
third_party/python/pyasn1/tests/compat/test_binary.py
third_party/python/pyasn1/tests/compat/test_integer.py
third_party/python/pyasn1/tests/compat/test_octets.py
third_party/python/pyasn1/tests/test_debug.py
third_party/python/pyasn1/tests/type/__init__.py
third_party/python/pyasn1/tests/type/__main__.py
third_party/python/pyasn1/tests/type/test_char.py
third_party/python/pyasn1/tests/type/test_constraint.py
third_party/python/pyasn1/tests/type/test_namedtype.py
third_party/python/pyasn1/tests/type/test_namedval.py
third_party/python/pyasn1/tests/type/test_tag.py
third_party/python/pyasn1/tests/type/test_univ.py
third_party/python/pyasn1/tests/type/test_useful.py
deleted file mode 100644
--- a/third_party/python/pyasn1/CHANGES
+++ /dev/null
@@ -1,278 +0,0 @@
-Revision 0.1.7
---------------
-
-- License updated to vanilla BSD 2-Clause to ease package use
-  (http://opensource.org/licenses/BSD-2-Clause).
-- Test suite made discoverable by unittest/unittest2 discovery feature.
-- Fix to decoder working on indefinite length substrate -- end-of-octets
-  marker is now detected by both tag and value. Otherwise zero values may
-  interfere with end-of-octets marker.
-- Fix to decoder to fail in cases where tagFormat indicates inappropriate
-  format for the type (e.g. BOOLEAN is always PRIMITIVE, SET is always 
-  CONSTRUCTED and OCTET STRING is either of the two)
-- Fix to REAL type encoder to force primitive encoding form encoding.
-- Fix to CHOICE decoder to handle explicitly tagged, indefinite length
-  mode encoding
-- Fix to REAL type decoder to handle negative REAL values correctly. Test
-  case added.
-
-Revision 0.1.6
---------------
-
-- The compact (valueless) way of encoding zero INTEGERs introduced in
-  0.1.5 seems to fail miserably as the world is filled with broken
-  BER decoders. So we had to back off the *encoder* for a while.
-  There's still the IntegerEncoder.supportCompactZero flag which
-  enables compact encoding form whenever it evaluates to True.
-- Report package version on debugging code initialization.
-
-Revision 0.1.5
---------------
-
-- Documentation updated and split into chapters to better match
-  web-site contents.
-- Make prettyPrint() working for non-initialized pyasn1 data objects. It
-  used to throw an exception.
-- Fix to encoder to produce empty-payload INTEGER values for zeros
-- Fix to decoder to support empty-payload INTEGER and REAL values
-- Fix to unit test suites imports to be able to run each from
-  their current directory
-
-Revision 0.1.4
---------------
-
-- Built-in codec debugging facility added
-- Added some more checks to ObjectIdentifier BER encoder catching
-  posible 2^8 overflow condition by two leading sub-OIDs
-- Implementations overriding the AbstractDecoder.valueDecoder method
-  changed to return the rest of substrate behind the item being processed
-  rather than the unprocessed substrate within the item (which is usually
-  empty).
-- Decoder's recursiveFlag feature generalized as a user callback function
-  which is passed an uninitialized object recovered from substrate and
-  its uninterpreted payload.
-- Catch inappropriate substrate type passed to decoder.
-- Expose tagMap/typeMap/Decoder objects at DER decoder to uniform API.
-- Obsolete __init__.MajorVersionId replaced with __init__.__version__
-  which is now in-sync with distutils.
-- Package classifiers updated.
-- The __init__.py's made non-empty (rumors are that they may be optimized 
-  out by package managers).
-- Bail out gracefully whenever Python version is older than 2.4.
-- Fix to Real codec exponent encoding (should be in 2's complement form),
-  some more test cases added.
-- Fix in Boolean truth testing built-in methods
-- Fix to substrate underrun error handling at ObjectIdentifier BER decoder
-- Fix to BER Boolean decoder that allows other pre-computed
-  values besides 0 and 1
-- Fix to leading 0x80 octet handling in DER/CER/DER ObjectIdentifier decoder.
-  See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
-
-Revision 0.1.3
---------------
-
-- Include class name into asn1 value constraint violation exception.
-- Fix to OctetString.prettyOut() method that looses leading zero when
-  building hex string.
-
-Revision 0.1.2
---------------
-
-- Fix to __long__() to actually return longs on py2k
-- Fix to OctetString.__str__() workings of a non-initialized object.
-- Fix to quote initializer of OctetString.__repr__()
-- Minor fix towards ObjectIdentifier.prettyIn() reliability
-- ObjectIdentifier.__str__() is aliased to prettyPrint()
-- Exlicit repr() calls replaced with '%r'
-
-Revision 0.1.1
---------------
-
-- Hex/bin string initializer to OctetString object reworked
-  (in a backward-incompatible manner)
-- Fixed float() infinity compatibility issue (affects 2.5 and earlier)
-- Fixed a bug/typo at Boolean CER encoder.
-- Major overhawl for Python 2.4 -- 3.2 compatibility:
-  + get rid of old-style types
-  + drop string module usage
-  + switch to rich comparation
-  + drop explicit long integer type use
-  + map()/filter() replaced with list comprehension
-  + apply() replaced with */**args
-  + switched to use 'key' sort() callback function
-  + support both __nonzero__() and __bool__() methods
-  + modified not to use py3k-incompatible exception syntax
-  + getslice() operator fully replaced with getitem()
-  + dictionary operations made 2K/3K compatible
-  + base type for encoding substrate and OctetString-based types
-    is now 'bytes' when running py3k and 'str' otherwise
-  + OctetString and derivatives now unicode compliant.
-  + OctetString now supports two python-neutral getters: asOcts() & asInts()
-  + print OctetString content in hex whenever it is not printable otherwise
-  + in test suite, implicit relative import replaced with the absolute one
-  + in test suite, string constants replaced with numerics
-
-Revision 0.0.13
----------------
-
-- Fix to base10 normalization function that loops on univ.Real(0)
-
-Revision 0.0.13b
-----------------
-
-- ASN.1 Real type is now supported properly.
-- Objects of Constructed types now support __setitem__()
-- Set/Sequence objects can now be addressed by their field names (string index)
-  and position (integer index).
-- Typo fix to ber.SetDecoder code that prevented guided decoding operation.
-- Fix to explicitly tagged items decoding support.
-- Fix to OctetString.prettyPrint() to better handle non-printable content.
-- Fix to repr() workings of Choice objects.
-
-Revision 0.0.13a
-----------------
-
-- Major codec re-design.
-- Documentation significantly improved.
-- ASN.1 Any type is now supported.
-- All example ASN.1 modules moved to separate pyasn1-modules package.
-- Fix to initial sub-OID overflow condition detection an encoder.
-- BitString initialization value verification improved.
-- The Set/Sequence.getNameByPosition() method implemented.
-- Fix to proper behaviour of PermittedAlphabetConstraint object.
-- Fix to improper Boolean substrate handling at CER/DER decoders.
-- Changes towards performance improvement:
-  + all dict.has_key() & dict.get() invocations replaced with modern syntax
-    (this breaks compatibility with Python 2.1 and older).
-  + tag and tagset caches introduced to decoder
-  + decoder code improved to prevent unnecessary pyasn1 objects creation
-  + allow disabling components verification when setting components to
-    structured types, this is used by decoder whilst running in guided mode.
-  + BER decoder for integer values now looks up a small set of pre-computed
-    substrate values to save on decoding.
-  + a few pre-computed values configured to ObjectIdentifier BER encoder.
-  + ChoiceDecoder split-off SequenceOf one to save on unnecessary checks.
-  + replace slow hasattr()/getattr() calls with isinstance() introspection.
-  + track the number of initialized components of Constructed types to save
-    on default/optional components initialization.
-  + added a shortcut ObjectIdentifier.asTuple() to be used instead of
-    __getitem__() in hotspots.
-  + use Tag.asTuple() and pure integers at tag encoder.
-  + introduce and use in decoder the baseTagSet attribute of the built-in
-    ASN.1 types.
-
-Revision 0.0.12a
-----------------
-
-- The individual tag/length/value processing methods of 
-  encoder.AbstractItemEncoder renamed (leading underscore stripped)
-  to promote overloading in cases where partial substrate processing
-  is required.
-- The ocsp.py, ldap.py example scripts added.
-- Fix to univ.ObjectIdentifier input value handler to disallow negative
-  sub-IDs.
-
-Revision 0.0.11a
-----------------
-
-- Decoder can now treat values of unknown types as opaque OctetString.
-- Fix to Set/SetOf type decoder to handle uninitialized scalar SetOf 
-  components correctly.
-
-Revision 0.0.10a
-----------------
-
-- API versioning mechanics retired (pyasn1.v1 -> pyasn1) what makes
-  it possible to zip-import pyasn1 sources (used by egg and py2exe).
-
-Revision 0.0.9a
----------------
-
-- Allow any non-zero values in Boolean type BER decoder, as it's in
-  accordnance with the standard.
-
-Revision 0.0.8a
----------------
-
-- Integer.__index__() now supported (for Python 2.5+).
-- Fix to empty value encoding in BitString encoder, test case added.
-- Fix to SequenceOf decoder that prevents it skipping possible Choice
-  typed inner component.
-- Choice.getName() method added for getting currently set component
-  name.
-- OctetsString.prettyPrint() does a single str() against its value
-  eliminating an extra quotes.
-
-Revision 0.0.7a
----------------
-
-- Large tags (>31) now supported by codecs.
-- Fix to encoder to properly handle explicitly tagged untagged items.
-- All possible value lengths (up to 256^126) now supported by encoders.
-- Fix to Tag class constructor to prevent negative IDs.
-
-Revision 0.0.6a
----------------
-
-- Make use of setuptools.
-- Constraints derivation verification (isSuperTypeOf()/isSubTypeOf()) fixed.
-- Fix to constraints comparation logic -- can't cmp() hash values as it
-  may cause false positives due to hash conflicts.
-
-Revision 0.0.5a
----------------
-
-- Integer BER codec reworked fixing negative values encoding bug.
-- clone() and subtype() methods of Constructed ASN.1 classes now 
-  accept optional cloneValueFlag flag which controls original value
-  inheritance. The default is *not* to inherit original value for 
-  performance reasons (this may affect backward compatibility).
-  Performance penalty may be huge on deeply nested Constructed objects
-  re-creation.
-- Base ASN.1 types (pyasn1.type.univ.*) do not have default values
-  anymore. They remain uninitialized acting as ASN.1 types. In 
-  this model, initialized ASN.1 types represent either types with
-  default value installed or a type instance.
-- Decoders' prototypes are now class instances rather than classes.
-  This is to simplify initial value installation to decoder's
-  prototype value.
-- Bugfix to BitString BER decoder (trailing bits not regarded).
-- Bugfix to Constraints use as mapping keys.
-- Bugfix to Integer & BitString clone() methods
-- Bugix to the way to distinguish Set from SetOf at CER/DER SetOfEncoder
-- Adjustments to make it running on Python 1.5.
-- In tests, substrate constants converted from hex escaped literals into
-  octals to overcome indefinite hex width issue occuring in young Python.
-- Minor performance optimization of TagSet.isSuperTagSetOf() method
-- examples/sshkey.py added
-
-Revision 0.0.4a
----------------
-
-* Asn1ItemBase.prettyPrinter() -> *.prettyPrint()
-
-Revision 0.0.3a
----------------
-
-* Simple ASN1 objects now hash to their Python value and don't
-  depend upon tag/constraints/etc.
-* prettyIn & prettyOut methods of SimplleAsn1Object become public
-* many syntax fixes
-
-Revision 0.0.2a
----------------
-
-* ConstraintsIntersection.isSuperTypeOf() and 
-  ConstraintsIntersection.hasConstraint() implemented
-* Bugfix to NamedValues initialization code
-* +/- operators added to NamedValues objects
-* Integer.__abs__() & Integer.subtype() added
-* ObjectIdentifier.prettyOut() fixes
-* Allow subclass components at SequenceAndSetBase
-* AbstractConstraint.__cmp__() dropped
-* error.Asn1Error replaced with error.PyAsn1Error
-
-Revision 0.0.1a
----------------
-
-* Initial public alpha release
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/CHANGES.rst
@@ -0,0 +1,576 @@
+
+Revision 0.3.7, released 04-10-2017
+-----------------------------------
+
+- Fixed ASN.1 time types pickling/deepcopy'ing
+
+Revision 0.3.6, released 21-09-2017
+-----------------------------------
+
+- End-of-octets encoding optimized at ASN.1 encoders
+- The __getitem__/__setitem__ behavior of Set/Sequence and SetOf/SequenceOf
+  objects aligned with the canonical Mapping and Sequence protocols in part
+- Fixed crash in ASN.1 encoder when encoding an explicitly tagged
+  component of a Sequence
+
+Revision 0.3.5, released 16-09-2017
+-----------------------------------
+
+- Codecs signatures unified and pass the options kwargs through the
+  call chain
+- Explicit tag encoding optimized to avoid unnecessary copying
+- End-of-octets sentinel encoding optimized
+- Refactored ASN.1 codecs properties to silently enforce proper
+  length and chunk size encoding modes
+- Fixed DER encoder to always produce primitive encoding
+- Fixed crash at SequenceOf native decoder
+- Fixed Real.prettyPrint() to fail gracefully on overflow
+- Fixed a couple of crashes when debug mode is enabled
+
+Revision 0.3.4, released 07-09-2017
+-----------------------------------
+
+- Fixed Native encoder to handle SEQUENCE/SET objects without
+  the componentType property
+- Added missing component-less SEQUENCE/SET objects dict duck-typing support
+- Fixed unnecessary duplicate tags detection at NamesType.tagMap
+- Fixed crash at SEQUENCE and SEQUENCE OF CER encoder when running
+  in schemaless mode
+- Fixed Character types instantiation from OctetString type -- double
+  unicode decoding may have scrambled the data
+
+Revision 0.3.3, released 27-08-2017
+-----------------------------------
+
+- Improved ASN.1 types instantiation performance
+- Improved BER/CER/DER decoder performance by not unconditionally casting
+  substrate into str/bytes.
+- Fixed exponential index size growth bug when building ambiguous
+  NamedTypes tree
+- Fixed constructed types decoding failure at BER codec if running
+  in schema-less mode
+- Fixed crash on prettyPrint'ing a SEQUENCE with no defined components
+- Fixed SetOf ordering at CER/DER encoder
+- Fixed crash on conditional binascii module import
+- Fix to TagSet hash value build
+
+Revision 0.3.2, released 04-08-2017
+-----------------------------------
+
+- Fixed SequenceOf/SetOf types initialization syntax to remain
+  backward compatible with pyasn1 0.2.*
+- Rectified thread safety issues by moving lazy, run-time computation
+  into object initializer.
+- Fixed .isValue property to return True for empty SetOf/SequenceOf
+  objects
+- Fixed GeneralizedTime/UTCTime CER/DER codecs to actually get invoked
+- Fixed DER/CER encoders handling optional SEQUENCE/SET fields containing
+  nested SEQUENCE/SET with optional fields.
+- Fixed crash in SequenceOf/SetOf pretty printing and decoding (in some
+  cases)
+- Fixed documentation markup issues.
+
+Revision 0.3.1, released 26-07-2017
+-----------------------------------
+
+- ASN.1 types __init__(), .clone() and .subtype() signatures
+  refactored into keyword arguments to simplify their signatures.
+- ASN.1 types initialization refactored to minimize the use of
+  relatively expensive isNoValue() call
+- Lazily pre-populate list of values of Sequence/Set/Choice types
+- NamedTypes comparison made more efficient
+- More efficient constraints computation and code clean up
+- The __getitem__() implementation of some ASN.1 types & tag object
+  refactored for better performance
+- BER/CER/DER value encoders refactored to produce either tuple of
+  bytes or octet-stream depending on what is more optimal
+- Reduced the frequency of expensive isinstance() calls
+- Tag-related classes optimized, refactored into properties and
+  documented.
+- The NamedValues implementation refactored to mimic Python dict, its use
+  in ASN.1 types refactored into properties and better documented.
+  WARNING: this change introduces a deviation from original API.
+- NamedType family of classes overhauled, optimized and documented.
+- The `componentType` attribute of constructed ASN.1 types turned
+  read-only on instances.
+- Sequence/Set DER/CER/DER decoder optimized to skip the case of
+  reordered components handling when not necessary.
+- Tags and constraints-related getter methods refactored into read-only
+  instance attributes.
+- The .hasValue() method refactored into .isValue property. All ASN.1
+  objects now support them, not just scalars.
+- The Real.{isInfinity, isPlusInfinity, isMinusInfinity} methods
+  refactored into properties and renamed into IsInf, IsPlusInf and isMinusInf
+- The end-of-octets type refactored to ensure it is a singleton. Codecs
+  changed to rely on that for better performance.
+- Codecs lookup made more efficient at BER/CER/DER decoder main loop by
+  assigning `typeId` to every ASN.1 type, not just ambiguous ones.
+- The .getComponent*() methods of constructed ASN.1 types changed
+  to lazily instantiate underlying type rather than return `None`.
+  This should simplify its API as initialization like `X[0][1] = 2` becomes
+  possible.
+  WARNING: this change introduces a deviation from the original API.
+- The .setComponent*() methods of SetOf/SequenceOf types changed not
+  to allow uninitialized "holes" inside the sequences of their components.
+  They now behave similarly to Python lists.
+  WARNING: this change introduces a deviation from the original API.
+- Default and optional components en/decoding of Constructed type
+  refactored towards better efficiency and more control.
+- OctetsString and Any decoder optimized to avoid creating ASN.1
+  objects for chunks of substrate. Instead they now join substrate
+  chunks together and create ASN.1 object from it just once.
+- The GeneralizedTime and UTCTime types now support to/from Python
+  datetime object conversion.
+- Unit tests added for the `compat` sub-package.
+- Fixed BitString named bits initialization bug.
+- Fixed non-functional tag cache (when running Python 2) at DER decoder.
+- Fixed chunked encoding restriction on DER encoder.
+- Fixed SET components ordering at DER encoder.
+- Fixed BIT STRING & OCTET STRING encoding to be always non-chunked (e.g.
+  primitive) at DER encoder
+- Fixed `compat.integer.from_bytes()` behaviour on empty input.
+
+Revision 0.2.3, released 25-02-2017
+-----------------------------------
+
+- Improved SEQUENCE/SET/CHOICE decoding performance by maintaining a single shared
+  NamedType object for all instances of SEQUENCE/SET object.
+- Improved INTEGER encoding/decoding by switching to Python's built-in
+  integer serialization functions.
+- Improved BitString performance by rebasing it onto Python int type and leveraging
+  fast Integer serialization functions.
+- BitString type usability improved in many ways: for example bitshifting and
+  numeric operation on BitString is now possible.
+- Minor ObjectIdentifier type performance optimization.
+- ASN.1 character types refactored to keep unicode contents internally
+  (rather than serialized octet stream) and duck-type it directly.
+- ASN.1 OctetString initialized from a Python object performs bytes()
+  on it when running on Python 3 (used to do str() which is probably
+  less logical).
+- Missing support for NoValue.__sizeof__ added.
+- Added checks to make sure SEQUENCE/SET components being assigned
+  match the prototypes.
+- Setter methods for constructed types consistently accept matchTags
+  and matchConstraints flags to control the strictness of inner
+  components compatibility verification. Previously, these checks
+  were tied to verifyConstraints flag, now they are all independent.
+- General documentation improvements here and there.
+- Fix to __reversed__() magic to make it returning an iterator.
+- Test suite simplified and unified.
+- The __all__ variable added to most of the Python modules.
+- The "test" directory renamed into "tests" not to collide with
+  the "test" module.
+
+Revision 0.2.2, released 07-02-2017
+-----------------------------------
+
+- FIX TO A SECURITY WEAKNESS: define length only decoders could have successfully
+  processed indefinite length serialization.
+- FIX TO A SECURITY WEAKNESS: canonical decoders (CER/DER) may have successfully
+  consumed non-canonical variations of (otherwise valid) serialization.
+- Broken Enumerated subtyping fixed.
+
+Revision 0.2.1, released 05-02-2017
+-----------------------------------
+
+- FIX TO A SECURITY WEAKNESS: BER decoder improperly cached long tags.
+- New "native" codec implemented to transform pyasn1 types to Python built-in types and back.
+- Switched to new-style classes.
+- Sphinx documentation added.
+- BitString improvements:
+
+  * simple string of binary digits is now supported as initializer
+  * default str() yields string of binary digits (used to yield str(tuple())
+  * binValue and hexValue initializers added
+  * .asNumbers(), .asOctets() and asInteger() representation added
+
+- Components of constructed ASN.1 types can now be populated with
+  uninitialized ASN.1 objects by assigning either noValue sentinel or
+  setupComponent() function return in addition to now-legacy None sentinel.
+  This should improve code readability.
+- NoValue class improved to become a singleton and catch more kinds
+  of access to it.
+- Compatibility wrappers str2octs() and oct2strs() fixed to run over
+  iso-8859-1 encoding.
+- Integer changed to emit Real instance if division produces a float.
+- True division operation now supported by Integer type.
+- The __contains__(), __reverse__() methods implemented for container types
+- Iterator protocol support implemented for all container types.
+  Warning, warning, warning: this change may potentially affect backward
+  compatibility when:
+
+  * user class overrides __getitem__() without overriding __iter__()
+  * when user code iterates over SEQUENCE object to get its components (now keys will be yielded)
+
+- Almost complete Python list and dict protocols added to SequenceOf/SetOf and
+  Sequence/Set respectively
+- Fix to divmod operation implementation in Integer type.
+- Fix to IntegerDecoder's precomputed value map on Python 3.
+- Fix to base ASN.1 types to run in "unicode_literals" mode.
+- Fix to composite constraints "+" operands ordering (AbstractConstraintSet.__radd__)
+- Fix to constraints merge in .subtype() -- on merge existing constraints are
+  expanded to accommodate new constraints, not the other way round. When existing
+  constraints are wrapped in ConstraintsIntersection composite, additional
+  constraints being added on subtyping effectively further narrow the set of
+  allowed values, which aligns well with the notion of subtyping.
+- Fix to NamedTypes methods to handle .getTagMap() returning None
+- Fix to Set/Sequence.setDefaultComponents() to return self
+- Copyright notice added to non-trivial source code files.
+- Author's email changed, copyright extended to 2017
+
+Revision 0.1.9, released 28-09-2015
+-----------------------------------
+
+- Wheel distribution format now supported.
+- Extensions added to text files, CVS attic flushed.
+- Fix to make uninitialized pyasn1 objects failing properly on hash().
+- Fix to ObjectIdentifier initialization from unicode string.
+- Fix to CER/DER Boolean decoder - fail on non single-octet payload.
+
+Revision 0.1.8, released 22-06-2015
+-----------------------------------
+
+- ObjectIdentifier codec fixed to work properly with arc 0 and arc 2 values.
+- Explicit limit on ObjectIdentifier arc value size removed.
+- Unicode initializer support added to OctetString type and derivatives.
+- New prettyPrintType() abstract method implemented to base pyasn1 types
+  to facilitate encoding errors analysis.
+- The __str__() method implemented to Tag, TagSet and TagMap classes to
+  ease encoding errors troubleshooting.
+  easing encoding errors
+- Fix to SEQUENCE and SET types to give them their private componentTypes
+  collection (which is a NamedTypes object) so that they won't collide in
+  a MT execution environment.
+- Missing T61String,ISO646String character types and ObjectDescriptor useful
+  type added.
+- Distribute is gone, switched to setuptools completely.
+- Missing NamedValues.__repr__() added.
+- The base.NoValue() class, that indicates uninitialized ASN.1 object,
+  made public.
+- The base.NoValue() class instances now support __repr__() what makes
+  possible to perform repr() on uninitialized pyasn1 types objects.
+- When comparing ASN.1 types, by-tag and/or by-constraints matching
+  can now be performed with the isSuperTypeOf()/isSameTypeWith() optional
+  flags.
+- Constructed types now verify their consistency by invoking 
+  isSameTypeWith(matchTags=True, matchConstraints=False) and
+  isSuperTypeOf(matchTags=False, matchConstraints=True) for each of their
+  components rather than isSuperTypeOf() as it used to be. Constriants check 
+  could be enforced to isSameTypeWith() with the strictConstraints=True
+  constructed classes attribute.
+- Constructed types can now be initialized with new .setComponents() method
+  which accepts both var-args and keyword-args. Default repr() modified to
+  reflect this change.
+- NamedTypes() and NamedValues() made comparable.
+- Test coverage extended to cover pyasn1 types __repr__() function.
+- The abs(Integer()) & abs(Real()) operation now returns respective pyasn1 
+  type, not a Python type.
+- More Python magic methods implementations added to Integer & Real classes
+  (e.g.  __pos__, __neg__, __round__, __floor__, __ceil__, __trunc__)
+- The Integer.__invert__ Python magic method implemented.
+- The OctetString.__int__() and .__float__() magic methods implemented.
+- Handle the case of null writer at Debug printer.
+- BitString encoder/decoder performance improved.
+- Built-in debugging is now based on Python logging module.
+- Fix to NamedType.__repr__() to work properly.
+- Fixes to __repr__() implementation of many built-in ASN.1 types to take into
+  account all of their initializers such as tagSet, subtypeSpec etc.
+- String typed float initializer to REAL type now supported.
+- Float typed mantissa initializer to REAL type for base 2 added.
+- Encoding bases 8 and 16 support for REAL type binary encoder added.
+- More strict CER/DER encoders added for GeneralizedTime and UTCTime types.
+- Asn1Item.hasValue() added to easily distinguish initalized ASN.1 objects
+  from uninitialized ones (e.g. pure types).
+- Fix to REAL type binary decoder to handle different bases and scale factor.
+- Fix to TagSet.repr() to include [obsolete] baseTag information.
+- Fix to broken REAL type decoding handling.
+- Fix to BitString and OctetString decoders dealing with constructed
+  encoding -- it used to be possible to embed other types in substrate.
+- DER codec hardened not to tolerate indefinite length encoding/decoding.
+- Fix to end-of-octest sentinel handling:
+
+  + require strict two-zeros sentinel encoding
+  + recognize EOO sentinel only when explicitly requested by caller
+    of the decoder via allowEoo=True parameter (warning: API change)
+
+Revision 0.1.7
+--------------
+
+- License updated to vanilla BSD 2-Clause to ease package use
+  (http://opensource.org/licenses/BSD-2-Clause).
+- Test suite made discoverable by unittest/unittest2 discovery feature.
+- Fix to decoder working on indefinite length substrate -- end-of-octets
+  marker is now detected by both tag and value. Otherwise zero values may
+  interfere with end-of-octets marker.
+- Fix to decoder to fail in cases where tagFormat indicates inappropriate
+  format for the type (e.g. BOOLEAN is always PRIMITIVE, SET is always 
+  CONSTRUCTED and OCTET STRING is either of the two)
+- Fix to REAL type encoder to force primitive encoding form encoding.
+- Fix to CHOICE decoder to handle explicitly tagged, indefinite length
+  mode encoding
+- Fix to REAL type decoder to handle negative REAL values correctly. Test
+  case added.
+
+Revision 0.1.6
+--------------
+
+- The compact (valueless) way of encoding zero INTEGERs introduced in
+  0.1.5 seems to fail miserably as the world is filled with broken
+  BER decoders. So we had to back off the *encoder* for a while.
+  There's still the IntegerEncoder.supportCompactZero flag which
+  enables compact encoding form whenever it evaluates to True.
+- Report package version on debugging code initialization.
+
+Revision 0.1.5
+--------------
+
+- Documentation updated and split into chapters to better match
+  web-site contents.
+- Make prettyPrint() working for non-initialized pyasn1 data objects. It
+  used to throw an exception.
+- Fix to encoder to produce empty-payload INTEGER values for zeros
+- Fix to decoder to support empty-payload INTEGER and REAL values
+- Fix to unit test suites imports to be able to run each from
+  their current directory
+
+Revision 0.1.4
+--------------
+
+- Built-in codec debugging facility added
+- Added some more checks to ObjectIdentifier BER encoder catching
+  posible 2^8 overflow condition by two leading sub-OIDs
+- Implementations overriding the AbstractDecoder.valueDecoder method
+  changed to return the rest of substrate behind the item being processed
+  rather than the unprocessed substrate within the item (which is usually
+  empty).
+- Decoder's recursiveFlag feature generalized as a user callback function
+  which is passed an uninitialized object recovered from substrate and
+  its uninterpreted payload.
+- Catch inappropriate substrate type passed to decoder.
+- Expose tagMap/typeMap/Decoder objects at DER decoder to uniform API.
+- Obsolete __init__.MajorVersionId replaced with __init__.__version__
+  which is now in-sync with distutils.
+- Package classifiers updated.
+- The __init__.py's made non-empty (rumors are that they may be optimized 
+  out by package managers).
+- Bail out gracefully whenever Python version is older than 2.4.
+- Fix to Real codec exponent encoding (should be in 2's complement form),
+  some more test cases added.
+- Fix in Boolean truth testing built-in methods
+- Fix to substrate underrun error handling at ObjectIdentifier BER decoder
+- Fix to BER Boolean decoder that allows other pre-computed
+  values besides 0 and 1
+- Fix to leading 0x80 octet handling in DER/CER/DER ObjectIdentifier decoder.
+  See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
+
+Revision 0.1.3
+--------------
+
+- Include class name into asn1 value constraint violation exception.
+- Fix to OctetString.prettyOut() method that looses leading zero when
+  building hex string.
+
+Revision 0.1.2
+--------------
+
+- Fix to __long__() to actually return longs on py2k
+- Fix to OctetString.__str__() workings of a non-initialized object.
+- Fix to quote initializer of OctetString.__repr__()
+- Minor fix towards ObjectIdentifier.prettyIn() reliability
+- ObjectIdentifier.__str__() is aliased to prettyPrint()
+- Exlicit repr() calls replaced with '%r'
+
+Revision 0.1.1
+--------------
+
+- Hex/bin string initializer to OctetString object reworked
+  (in a backward-incompatible manner)
+- Fixed float() infinity compatibility issue (affects 2.5 and earlier)
+- Fixed a bug/typo at Boolean CER encoder.
+- Major overhawl for Python 2.4 -- 3.2 compatibility:
+  + get rid of old-style types
+  + drop string module usage
+  + switch to rich comparation
+  + drop explicit long integer type use
+  + map()/filter() replaced with list comprehension
+  + apply() replaced with \*/\*\*args
+  + switched to use 'key' sort() callback function
+  + support both __nonzero__() and __bool__() methods
+  + modified not to use py3k-incompatible exception syntax
+  + getslice() operator fully replaced with getitem()
+  + dictionary operations made 2K/3K compatible
+  + base type for encoding substrate and OctetString-based types
+  is now 'bytes' when running py3k and 'str' otherwise
+  + OctetString and derivatives now unicode compliant.
+  + OctetString now supports two python-neutral getters: asOcts() & asInts()
+  + print OctetString content in hex whenever it is not printable otherwise
+  + in test suite, implicit relative import replaced with the absolute one
+  + in test suite, string constants replaced with numerics
+
+Revision 0.0.13
+---------------
+
+- Fix to base10 normalization function that loops on univ.Real(0)
+
+Revision 0.0.13b
+----------------
+
+- ASN.1 Real type is now supported properly.
+- Objects of Constructed types now support __setitem__()
+- Set/Sequence objects can now be addressed by their field names (string index)
+  and position (integer index).
+- Typo fix to ber.SetDecoder code that prevented with schema decoding
+  operation.
+- Fix to explicitly tagged items decoding support.
+- Fix to OctetString.prettyPrint() to better handle non-printable content.
+- Fix to repr() workings of Choice objects.
+
+Revision 0.0.13a
+----------------
+
+- Major codec re-design.
+- Documentation significantly improved.
+- ASN.1 Any type is now supported.
+- All example ASN.1 modules moved to separate pyasn1-modules package.
+- Fix to initial sub-OID overflow condition detection an encoder.
+- BitString initialization value verification improved.
+- The Set/Sequence.getNameByPosition() method implemented.
+- Fix to proper behaviour of PermittedAlphabetConstraint object.
+- Fix to improper Boolean substrate handling at CER/DER decoders.
+- Changes towards performance improvement:
+
+  + all dict.has_key() & dict.get() invocations replaced with modern syntax
+    (this breaks compatibility with Python 2.1 and older).
+  + tag and tagset caches introduced to decoder
+  + decoder code improved to prevent unnecessary pyasn1 objects creation
+  + allow disabling components verification when setting components to
+    structured types, this is used by decoder whilst running with schema
+    mode.
+  + BER decoder for integer values now looks up a small set of pre-computed
+    substrate values to save on decoding.
+  + a few pre-computed values configured to ObjectIdentifier BER encoder.
+  + ChoiceDecoder split-off SequenceOf one to save on unnecessary checks.
+  + replace slow hasattr()/getattr() calls with isinstance() introspection.
+  + track the number of initialized components of Constructed types to save
+    on default/optional components initialization.
+  + added a shortcut ObjectIdentifier.asTuple() to be used instead of
+    __getitem__() in hotspots.
+  + use Tag.asTuple() and pure integers at tag encoder.
+  + introduce and use in decoder the baseTagSet attribute of the built-in
+    ASN.1 types.
+
+Revision 0.0.12a
+----------------
+
+- The individual tag/length/value processing methods of 
+  encoder.AbstractItemEncoder renamed (leading underscore stripped)
+  to promote overloading in cases where partial substrate processing
+  is required.
+- The ocsp.py, ldap.py example scripts added.
+- Fix to univ.ObjectIdentifier input value handler to disallow negative
+  sub-IDs.
+
+Revision 0.0.11a
+----------------
+
+- Decoder can now treat values of unknown types as opaque OctetString.
+- Fix to Set/SetOf type decoder to handle uninitialized scalar SetOf 
+  components correctly.
+
+Revision 0.0.10a
+----------------
+
+- API versioning mechanics retired (pyasn1.v1 -> pyasn1) what makes
+  it possible to zip-import pyasn1 sources (used by egg and py2exe).
+
+Revision 0.0.9a
+---------------
+
+- Allow any non-zero values in Boolean type BER decoder, as it's in
+  accordnance with the standard.
+
+Revision 0.0.8a
+---------------
+
+- Integer.__index__() now supported (for Python 2.5+).
+- Fix to empty value encoding in BitString encoder, test case added.
+- Fix to SequenceOf decoder that prevents it skipping possible Choice
+  typed inner component.
+- Choice.getName() method added for getting currently set component
+  name.
+- OctetsString.prettyPrint() does a single str() against its value
+  eliminating an extra quotes.
+
+Revision 0.0.7a
+---------------
+
+- Large tags (>31) now supported by codecs.
+- Fix to encoder to properly handle explicitly tagged untagged items.
+- All possible value lengths (up to 256^126) now supported by encoders.
+- Fix to Tag class constructor to prevent negative IDs.
+
+Revision 0.0.6a
+---------------
+
+- Make use of setuptools.
+- Constraints derivation verification (isSuperTypeOf()/isSubTypeOf()) fixed.
+- Fix to constraints comparation logic -- can't cmp() hash values as it
+  may cause false positives due to hash conflicts.
+
+Revision 0.0.5a
+---------------
+
+- Integer BER codec reworked fixing negative values encoding bug.
+- clone() and subtype() methods of Constructed ASN.1 classes now 
+  accept optional cloneValueFlag flag which controls original value
+  inheritance. The default is *not* to inherit original value for 
+  performance reasons (this may affect backward compatibility).
+  Performance penalty may be huge on deeply nested Constructed objects
+  re-creation.
+- Base ASN.1 types (pyasn1.type.univ.*) do not have default values
+  anymore. They remain uninitialized acting as ASN.1 types. In 
+  this model, initialized ASN.1 types represent either types with
+  default value installed or a type instance.
+- Decoders' prototypes are now class instances rather than classes.
+  This is to simplify initial value installation to decoder's
+  prototype value.
+- Bugfix to BitString BER decoder (trailing bits not regarded).
+- Bugfix to Constraints use as mapping keys.
+- Bugfix to Integer & BitString clone() methods
+- Bugix to the way to distinguish Set from SetOf at CER/DER SetOfEncoder
+- Adjustments to make it running on Python 1.5.
+- In tests, substrate constants converted from hex escaped literals into
+  octals to overcome indefinite hex width issue occuring in young Python.
+- Minor performance optimization of TagSet.isSuperTagSetOf() method
+- examples/sshkey.py added
+
+Revision 0.0.4a
+---------------
+
+* Asn1ItemBase.prettyPrinter() -> \*.prettyPrint()
+
+Revision 0.0.3a
+---------------
+
+* Simple ASN1 objects now hash to their Python value and don't
+  depend upon tag/constraints/etc.
+* prettyIn & prettyOut methods of SimplleAsn1Object become public
+* many syntax fixes
+
+Revision 0.0.2a
+---------------
+
+* ConstraintsIntersection.isSuperTypeOf() and 
+  ConstraintsIntersection.hasConstraint() implemented
+* Bugfix to NamedValues initialization code
+* +/- operators added to NamedValues objects
+* Integer.__abs__() & Integer.subtype() added
+* ObjectIdentifier.prettyOut() fixes
+* Allow subclass components at SequenceAndSetBase
+* AbstractConstraint.__cmp__() dropped
+* error.Asn1Error replaced with error.PyAsn1Error
+
+Revision 0.0.1a
+---------------
+
+* Initial public alpha release
deleted file mode 100644
--- a/third_party/python/pyasn1/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2005-2013, Ilya Etingof <ilya@glas.net>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-  * Redistributions of source code must retain the above copyright notice, 
-    this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright notice,
-    this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE. 
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/LICENSE.rst
@@ -0,0 +1,24 @@
+Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, 
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. 
--- a/third_party/python/pyasn1/MANIFEST.in
+++ b/third_party/python/pyasn1/MANIFEST.in
@@ -1,3 +1,5 @@
-include CHANGES README LICENSE THANKS TODO
-recursive-include test *.py
-recursive-include doc *.html
+include *.rst *.md
+recursive-include tests *.py
+recursive-include doc Makefile *.rst conf.py
+prune doc/build
+prune doc/source/.templates
\ No newline at end of file
--- a/third_party/python/pyasn1/PKG-INFO
+++ b/third_party/python/pyasn1/PKG-INFO
@@ -1,26 +1,33 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: pyasn1
-Version: 0.1.7
+Version: 0.3.7
 Summary: ASN.1 types and codecs
-Home-page: http://sourceforge.net/projects/pyasn1/
-Author: Ilya Etingof <ilya@glas.net>
-Author-email: ilya@glas.net
+Home-page: https://github.com/etingof/pyasn1
+Author: Ilya Etingof <etingof@gmail.com>
+Author-email: etingof@gmail.com
 License: BSD
-Description: A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
+Description: Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Education
 Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: Science/Research
 Classifier: Intended Audience :: System Administrators
 Classifier: Intended Audience :: Telecommunications Industry
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Communications
-Classifier: Topic :: Security :: Cryptography
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
deleted file mode 100644
--- a/third_party/python/pyasn1/README
+++ /dev/null
@@ -1,68 +0,0 @@
-
-ASN.1 library for Python
-------------------------
-
-This is an implementation of ASN.1 types and codecs in Python programming
-language. It has been first written to support particular protocol (SNMP)
-but then generalized to be suitable for a wide range of protocols
-based on ASN.1 specification.
-
-FEATURES
---------
-
-* Generic implementation of ASN.1 types (X.208)
-* Fully standard compliant BER/CER/DER codecs
-* 100% Python, works with Python 2.4 up to Python 3.3 (beta 1)
-* MT-safe
-
-MISFEATURES
------------
-
-* No ASN.1 compiler (by-hand ASN.1 spec compilation into Python code required)
-* Codecs are not restartable
-
-INSTALLATION
-------------
-
-The pyasn1 package uses setuptools/distutils for installation. Thus do
-either:
-
-$ easy_install pyasn1
-
-or
-
-$ tar zxf pyasn1-0.1.3.tar.gz
-$ cd pyasn1-0.1.3
-$ python setup.py install
-$ cd test
-$ python suite.py   # run unit tests
-
-OPERATION
----------
-
-Perhaps a typical use would involve [by-hand] compilation of your ASN.1
-specification into pyasn1-backed Python code at your application.
-
-For more information on pyasn1 APIs, please, refer to the 
-doc/pyasn1-tutorial.html file in the distribution.
-
-Also refer to example modules. Take a look at pyasn1-modules package -- maybe
-it already holds something useful to you.
-
-AVAILABILITY
-------------
-
-The pyasn1 package is distributed under terms and conditions of BSD-style
-license. See LICENSE file in the distribution. Source code is freely
-available from:
-
-http://pyasn1.sf.net
-
-
-FEEDBACK
---------
-
-Please, send your comments and fixes to mailing lists at project web site.
-
-=-=-=
-mailto: ilya@glas.net
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/README.md
@@ -0,0 +1,184 @@
+
+ASN.1 library for Python
+------------------------
+[![PyPI](https://img.shields.io/pypi/v/pyasn1.svg?maxAge=2592000)](https://pypi.python.org/pypi/pyasn1)
+[![Python Versions](https://img.shields.io/pypi/pyversions/pyasn1.svg)](https://pypi.python.org/pypi/pyasn1/)
+[![Build status](https://travis-ci.org/etingof/pyasn1.svg?branch=master)](https://secure.travis-ci.org/etingof/pyasn1)
+[![Coverage Status](https://img.shields.io/codecov/c/github/etingof/pyasn1.svg)](https://codecov.io/github/etingof/pyasn1)
+[![GitHub license](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/etingof/pyasn1/master/LICENSE.txt)
+
+This is a free and open source implementation of ASN.1 types and codecs
+as a Python package. It has been first written to support particular
+protocol (SNMP) but then generalized to be suitable for a wide range
+of protocols based on
+[ASN.1 specification](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items).
+
+Features
+--------
+
+* Generic implementation of ASN.1 types (X.208)
+* Standards compliant BER/CER/DER codecs
+* Dumps/loads ASN.1 structures from Python types
+* 100% Python, works with Python 2.4 up to Python 3.6
+* MT-safe
+* Contributed ASN.1 compiler [Asn1ate](https://github.com/kimgr/asn1ate)
+
+Why using pyasn1
+----------------
+
+ASN.1 solves the data serialization problem. This solution was
+designed long ago by the wise Ancients. Back then, they did not
+have the luxury of wasting bits. That is why ASN.1 is designed
+to serialize data structures of unbounded complexity into
+something compact and efficient when it comes to processing
+the data.
+
+That probably explains why many network protocols and file formats
+still rely on the 30+ years old technology. Including a number of
+high-profile Internet protocols and file formats.
+
+Quite a number of books cover the topic of ASN.1. 
+[Communication between heterogeneous systems](http://www.oss.com/asn1/dubuisson.html)
+by Olivier Dubuisson is one of those high quality books freely 
+available on the Internet.
+
+The pyasn1 package is designed to help Python programmers tackling
+network protocols and file formats at the comfort of their Python
+prompt. The tool struggles to capture all aspects of a rather
+complicated ASN.1 system and to represent it on the Python terms.
+
+How to use pyasn1
+-----------------
+
+With pyasn1 you can build Python objects from ASN.1 data structures.
+For example, the following ASN.1 data structure:
+
+```bash
+Record ::= SEQUENCE {
+  id        INTEGER,
+  room  [0] INTEGER OPTIONAL,
+  house [1] INTEGER DEFAULT 0
+}
+```
+
+Could be expressed in pyasn1 like this:
+
+```python
+class Record(Sequence):
+    componentType = NamedTypes(
+        NamedType('id', Integer()),
+        OptionalNamedType(
+            'room', Integer().subtype(
+                implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
+            )
+        ),
+        DefaultedNamedType(
+            'house', Integer(0).subtype(
+                implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
+            )
+        )
+    )
+```
+
+It is in the spirit of ASN.1 to take abstract data description 
+and turn it into a programming language specific form.
+Once you have your ASN.1 data structure expressed in Python, you
+can use it along the lines of similar Python type (e.g. ASN.1
+`SET` is similar to Python `dict`, `SET OF` to `list`):
+
+```python
+>>> record = Record()
+>>> record['id'] = 123
+>>> record['room'] = 321
+>>> print(record.prettyPrint())
+Record:
+ id=123
+ room=321
+>>>
+```
+
+Part of the power of ASN.1 comes from its serialization features. You
+can serialize your data structure and send it over the network.
+
+```python
+>>> from pyasn1.codec.der.encoder import encode
+>>> substrate = encode(record)
+>>> hexdump(substrate)
+00000: 30 07 02 01 7B 80 02 01 41
+```
+
+Conversely, you can turn serialized ASN.1 content, as received from
+network or read from a file, into a Python object which you can
+introspect, modify, encode and send back.
+
+```python
+>>> from pyasn1.codec.der.decoder import decode
+>>> received_record, rest_of_substrate = decode(substrate, asn1Spec=Record())
+>>>
+>>> for field in received_record:
+>>>    print('{} is {}'.format(field, received_record[field]))
+id is 123
+room is 321
+house is 0
+>>>
+>>> record == received_record
+True
+>>> received_record.update(room=123)
+>>> substrate = encode(received_record)
+>>> hexdump(substrate)
+00000: 30 06 02 01 7B 80 01 7B
+```
+
+The pyasn1 classes struggle to emulate their Python prototypes (e.g. int,
+list, dict etc.). But ASN.1 types exhibit more complicated behaviour.
+To make life easier for a Pythonista, they can turn their pyasn1
+classes into Python built-ins:
+
+```python
+>>> from pyasn1.codec.native.encoder import encode
+>>> encode(record)
+{'id': 123, 'room': 321, 'house': 0}
+```
+
+Or vice-versa -- you can initialize an ASN.1 structure from a tree of
+Python objects:
+
+```python
+>>> from pyasn1.codec.native.decoder import decode
+>>> record = decode({'id': 123, 'room': 321, 'house': 0}, asn1Spec=Record())
+>>> print(record.prettyPrint())
+Record:
+ id=123
+ room=321
+>>>
+```
+
+With ASN.1 design, serialization codecs are decoupled from data objects,
+so you could turn every single ASN.1 object into many different 
+serialized forms. As of this moment, pyasn1 supports BER, DER, CER and
+Python built-ins codecs. The extremely compact PER encoding is expected
+to be introduced in the upcoming pyasn1 release.
+
+More information on pyasn1 APIs can be found in the
+[documentation](http://pyasn1.sourceforge.net),
+compiled ASN.1 modules for different protocols and file formats
+could be found in the pyasn1-modules 
+[repo](https://github.com/etingof/pyasn1-modules).
+
+How to get pyasn1
+-----------------
+
+The pyasn1 package is distributed under terms and conditions of 2-clause
+BSD [license](http://pyasn1.sourceforge.net/license.html). Source code is freely
+available as a GitHub [repo](https://github.com/etingof/pyasn1).
+
+You could `pip install pyasn1` or download it from [PyPI](https://pypi.python.org/pypi/pyasn1).
+
+If something does not work as expected, 
+[open an issue](https://github.com/etingof/pyasn1/issues) at GitHub or
+post your question [on Stack Overflow](http://stackoverflow.com/questions/ask)
+or try browsing pyasn1 
+[mailing list archives](https://sourceforge.net/p/pyasn1/mailman/pyasn1-users/).
+
+Copyright (c) 2005-2017, [Ilya Etingof](mailto:etingof@gmail.com).
+All rights reserved.
deleted file mode 100644
--- a/third_party/python/pyasn1/THANKS
+++ /dev/null
@@ -1,4 +0,0 @@
-Denis S. Otkidach
-Gregory Golberg
-Bud P. Bruegger
-Jacek Konieczny
deleted file mode 100644
--- a/third_party/python/pyasn1/TODO
+++ /dev/null
@@ -1,36 +0,0 @@
-* Specialize ASN.1 character and useful types
-* Come up with simpler API for deeply nested constructed objects
-  addressing
-
-ber.decoder:
-* suspend codec on underrun error ?
-* class-static components map (in simple type classes)
-* present subtypes ?
-* component presence check wont work at innertypeconst
-* add the rest of ASN1 types/codecs
-* type vs value, defaultValue
-
-ber.encoder:
-* Asn1Item.clone() / shallowcopy issue
-* large length encoder?
-* codec restart
-* preserve compatible API whenever stateful codec gets implemented
-* restartable vs incremental
-* plan: make a stateless univeral decoder, then convert it to restartable
-       then to incremental
-
-type.useful:
-* may need to implement prettyIn/Out
-
-type.char:
-* may need to implement constraints
-
-type.univ:
-* simpler API to constructed objects: value init, recursive
-
-type.namedtypes
-* type vs tagset name convention
-
-general:
-
-* how untagged TagSet should be initialized?
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/TODO.rst
@@ -0,0 +1,92 @@
+
+Things to be done
+=================
+
+Big things to tackle, anyone interested is welcome to fork pyasn1, work on
+it and come up with a PR!
+
+New codecs
+----------
+
+* PER
+* OER
+* XER
+* LWER
+* JSON (alinged with existing experimental schemas)
+
+Lazy codecs
+-----------
+
+Implement a thin layer over base types to cache pieces
+of substrate being decoded till the very moment of ASN.1
+object access in the parse tree.
+
+Codecs generator interface
+--------------------------
+
+For indefinite length or chunked encoding mode, make codecs
+iterable producing/consuming substrate/objects.
+
+ASN.1 schema compiler
+---------------------
+
+Ideally, the compiler should parse modern schema files and be
+designed to emit code for arbitrary languages (including SQL).
+
+Base types
+----------
+
+Implement X.680 constructs, including information schema.
+
+Examples
+--------
+
+Add examples, including advanced/obscure use cases.
+
+Documentation
+-------------
+
+Document more API, add notes and example snippets.
+
+More fresh modules
+------------------
+
+Compile and ship more Pythonized ASN.1 modules for
+various ASN.1-based protocols (e.g. Kerberos etc).
+Refresh outdated modules in pyasn1-packages.
+
+Minor, housekeeping things
+--------------------------
+
+* more PEP8'ing at places
+* consider simplifying repr(), otherwise it tend to be too hard to grasp
+* Specialize ASN.1 character and useful types
+
+* ber.decoder:
+
+    * suspend codec on underrun error ?
+    * present subtypes ?
+    * component presence check wont work at innertypeconst
+    * type vs value, defaultValue
+
+* ber.encoder:
+
+    * Asn1Item.clone() / shallowcopy issue
+    * large length encoder?
+    * lookup type by tag first to allow custom codecs for non-base types
+
+* type.useful:
+
+    * may need to implement prettyIn/Out
+
+* type.char:
+
+    * may need to implement constraints
+
+* type.namedtypes
+
+    * type vs tagset name convention
+
+* how untagged TagSet should be initialized?
+
+* type and codecs for Real needs refactoring
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/Makefile
@@ -0,0 +1,192 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  applehelp  to make an Apple Help Book"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  xml        to make Docutils-native XML files"
+	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+	@echo "  coverage   to run coverage check of the documentation (if enabled)"
+
+clean:
+	rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyASN1.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyASN1.qhc"
+
+applehelp:
+	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+	@echo
+	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+	@echo "N.B. You won't be able to view it unless you put it in" \
+	      "~/Library/Documentation/Help or install it in your application" \
+	      "bundle."
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/PyASN1"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PyASN1"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through platex and dvipdfmx..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+
+coverage:
+	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+	@echo "Testing of coverage in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/coverage/python.txt."
+
+xml:
+	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+	@echo
+	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+	@echo
+	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/codecs.html
+++ /dev/null
@@ -1,503 +0,0 @@
-<html>
-<title>
-PyASN1 codecs
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-<h3>
-2. PyASN1 Codecs
-</h3>
-
-<p>
-In ASN.1 context, 
-<a href=http://en.wikipedia.org/wiki/Codec>codec</a>
-is a program that transforms between concrete data structures and a stream
-of octets, suitable for transmission over the wire. This serialized form of
-data is sometimes called <i>substrate</i> or <i>essence</i>.
-</p>
-
-<p>
-In pyasn1 implementation, substrate takes shape of Python 3 bytes or 
-Python 2 string objects.
-</p>
-
-<p>
-One of the properties of a codec is its ability to cope with incomplete
-data and/or substrate what implies codec to be stateful. In other words, 
-when decoder runs out of substrate and data item being recovered is still 
-incomplete, stateful codec would suspend and complete data item recovery 
-whenever the rest of substrate becomes available. Similarly, stateful encoder
-would encode data items in multiple steps waiting for source data to
-arrive. Codec restartability is especially important when application deals
-with large volumes of data and/or runs on low RAM. For an interesting
-discussion on codecs options and design choices, refer to
-<a href=http://directory.apache.org/subprojects/asn1/>Apache ASN.1 project</a>
-.
-</p>
-
-<p>
-As of this writing, codecs implemented in pyasn1 are all stateless, mostly
-to keep the code simple.
-</p>
-
-<p>
-The pyasn1 package currently supports 
-<a href=http://en.wikipedia.org/wiki/Basic_encoding_rules>BER</a> codec and
-its variations -- 
-<a href=http://en.wikipedia.org/wiki/Canonical_encoding_rules>CER</a> and
-<a href=http://en.wikipedia.org/wiki/Distinguished_encoding_rules>DER</a>.
-More ASN.1 codecs are planned for implementation in the future.
-</p>
-
-<a name="2.1"></a>
-<h4>
-2.1 Encoders
-</h4>
-
-<p>
-Encoder is used for transforming pyasn1 value objects into substrate. Only
-pyasn1 value objects could be serialized, attempts to process pyasn1 type
-objects will cause encoder failure.
-</p>
-
-<p>
-The following code will create a pyasn1 Integer object and serialize it with
-BER encoder:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(univ.Integer(123456))
-b'\x02\x03\x01\xe2@'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-BER standard also defines a so-called <i>indefinite length</i> encoding form
-which makes large data items processing more memory efficient. It is mostly
-useful when encoder does not have the whole value all at once and the
-length of the value can not be determined at the beginning of encoding.
-</p>
-
-<p>
-<i>Constructed encoding</i> is another feature of BER closely related to the
-indefinite length form. In essence, a large scalar value (such as ASN.1
-character BitString type) could be chopped into smaller chunks by encoder
-and transmitted incrementally to limit memory consumption. Unlike indefinite
-length case, the length of the whole value must be known in advance when
-using constructed, definite length encoding form.
-</p>
-
-<p>
-Since pyasn1 codecs are not restartable, pyasn1 encoder may only encode data
-item all at once. However, even in this case, generating indefinite length 
-encoding may help a low-memory receiver, running a restartable decoder,
-to process a large data item.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   defMode=False,
-...   maxChunkSize=8
-... )
-b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog\x00\x00'
->>>
->>> encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   maxChunkSize=8
-... )
-b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog'
-</pre>
-</td></tr></table>
-
-<p>
-The <b>defMode</b> encoder parameter disables definite length encoding mode,
-while the optional <b>maxChunkSize</b> parameter specifies desired
-substrate chunk size that influences memory requirements at the decoder's end.
-</p>
-
-<p>
-To use CER or DER encoders one needs to explicitly import and call them - the
-APIs are all compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> from pyasn1.codec.cer import encoder as cer_encoder
->>> from pyasn1.codec.der import encoder as der_encoder
->>> ber_encoder.encode(univ.Boolean(True))
-b'\x01\x01\x01'
->>> cer_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>> der_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2"></a>
-<h4>
-2.2 Decoders
-</h4>
-
-<p>
-In the process of decoding, pyasn1 value objects are created and linked to
-each other, based on the information containted in the substrate. Thus,
-the original pyasn1 value object(s) are recovered.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(univ.Boolean(True))
->>> decoder.decode(substrate)
-(Boolean('True(1)'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Commenting on the code snippet above, pyasn1 decoder accepts substrate
-as an argument and returns a tuple of pyasn1 value object (possibly
-a top-level one in case of constructed object) and unprocessed part
-of input substrate.
-</p>
-
-<p>
-All pyasn1 decoders can handle both definite and indefinite length
-encoding modes automatically, explicit switching into one mode
-to another is not required.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   defMode=False,
-...   maxChunkSize=8
-... )
->>> decoder.decode(substrate)
-(OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Speaking of BER/CER/DER encoding, in many situations substrate may not contain
-all necessary information needed for complete and accurate ASN.1 values
-recovery. The most obvious cases include implicitly tagged ASN.1 types
-and constrained types.
-</p>
-
-<p>
-As discussed earlier in this handbook, when an ASN.1 type is implicitly
-tagged, previous outermost tag is lost and never appears in substrate.
-If it is the base tag that gets lost, decoder is unable to pick type-specific
-value decoder at its table of built-in types, and therefore recover
-the value part, based only on the information contained in substrate. The
-approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
-a set of them) to <i>guide</i> the decoding process by matching [possibly
-incomplete] tags recovered from substrate with those found in prototype pyasn1
-type objects (also called pyasn1 specification object further in this paper).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import decoder
->>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
-Integer(12), b''
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Decoder would neither modify pyasn1 specification object nor use
-its current values (if it's a pyasn1 value object), but rather use it as
-a hint for choosing proper decoder and as a pattern for creating new objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> i = univ.Integer(12345).subtype(
-...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(i)
->>> substrate
-b'\x9f(\x0209'
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: 
-   TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>> decoder.decode(substrate, asn1Spec=i)
-(Integer(12345), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Notice in the example above, that an attempt to run decoder without passing
-pyasn1 specification object fails because recovered tag does not belong
-to any of the built-in types.
-</p>
-
-<p>
-Another important feature of guided decoder operation is the use of
-values constraints possibly present in pyasn1 specification object.
-To explain this, we will decode a random integer object into generic Integer
-and the constrained one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> from pyasn1.codec.ber import encoder, decoder
->>> class DialDigit(univ.Integer):
-...   subtypeSpec = constraint.ValueRangeConstraint(0,9)
->>> substrate = encoder.encode(univ.Integer(13))
->>> decoder.decode(substrate)
-(Integer(13), b'')
->>> decoder.decode(substrate, asn1Spec=DialDigit())
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueRangeConstraint(0, 9) failed at: 13
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Similarily to encoders, to use CER or DER decoders application has to
-explicitly import and call them - all APIs are compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
->>>
->>> from pyasn1.codec.ber import decoder as ber_decoder
->>> from pyasn1.codec.cer import decoder as cer_decoder
->>> from pyasn1.codec.der import decoder as der_decoder
->>> 
->>> ber_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> cer_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> der_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> 
-</pre>
-</td></tr></table>
-
-<a name="2.2.1"></a>
-<h4>
-2.2.1 Decoding untagged types
-</h4>
-
-<p>
-It has already been mentioned, that ASN.1 has two "special case" types:
-CHOICE and ANY. They are different from other types in part of 
-tagging - unless these two are additionally tagged, neither of them will
-have their own tag. Therefore these types become invisible in substrate
-and can not be recovered without passing pyasn1 specification object to
-decoder.
-</p>
-
-<p>
-To explain the issue, we will first prepare a Choice object to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('code', univ.Integer()),
-...     namedtype.NamedType('message', univ.OctetString())
-...   )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Let's now encode this Choice object and then decode its substrate
-with and without pyasn1 specification object:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(codeOrMessage)
->>> substrate
-b'\x04\x0fmy string value'
->>> encoder.encode(univ.OctetString('my string value'))
-b'\x04\x0fmy string value'
->>>
->>> decoder.decode(substrate)
-(OctetString(b'my string value'), b'')
->>> codeOrMessage, substrate = decoder.decode(substrate, asn1Spec=CodeOrMessage())
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-First thing to notice in the listing above is that the substrate produced
-for our Choice value object is equivalent to the substrate for an OctetString
-object initialized to the same value. In other words, any information about
-the Choice component is absent in encoding.
-</p>
-
-<p>
-Sure enough, that kind of substrate will decode into an OctetString object,
-unless original Choice type object is passed to decoder to guide the decoding
-process.
-</p>
-
-<p>
-Similarily untagged ANY type behaves differently on decoding phase - when
-decoder bumps into an Any object in pyasn1 specification, it stops decoding
-and puts all the substrate into a new Any value object in form of an octet
-string. Concerned application could then re-run decoder with an additional,
-more exact pyasn1 specification object to recover the contents of Any
-object.
-</p>
-
-<p>
-As it was mentioned elsewhere in this paper, Any type allows for incomplete
-or changing ASN.1 specification to be handled gracefully by decoder and
-applications.
-</p>
-
-<p>
-To illustrate the working of Any type, we'll have to make the stage
-by encoding a pyasn1 object and then putting its substrate into an any
-object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> innerSubstrate = encoder.encode(univ.Integer(1234))
->>> innerSubstrate
-b'\x02\x02\x04\xd2'
->>> any = univ.Any(innerSubstrate)
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> substrate = encoder.encode(any)
->>> substrate
-b'\x02\x02\x04\xd2'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As with Choice type encoding, there is no traces of Any type in substrate.
-Obviously, the substrate we are dealing with, will decode into the inner
-[Integer] component, unless pyasn1 specification is given to guide the 
-decoder. Continuing previous code:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
-
->>> decoder.decode(substrate)
-(Integer(1234), b'')
->>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> decoder.decode(str(any))
-(Integer(1234), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Both CHOICE and ANY types are widely used in practice. Reader is welcome to
-take a look at 
-<a href=http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>
-ASN.1 specifications of X.509 applications</a> for more information.
-</p>
-
-<a name="2.2.2"></a>
-<h4>
-2.2.2 Ignoring unknown types
-</h4>
-
-<p>
-When dealing with a loosely specified ASN.1 structure, the receiving
-end may not be aware of some types present in the substrate. It may be
-convenient then to turn decoder into a recovery mode. Whilst there, decoder
-will not bail out when hit an unknown tag but rather treat it as an Any
-type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> taggedInt = univ.Integer(12345).subtype(
-...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(taggedInt)
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>>
->>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
->>> decoder.decode(substrate)
-(Any(b'\x9f(\x0209'), '')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-It's also possible to configure a custom decoder, to handle unknown tags
-found in substrate. This can be done by means of <b>defaultRawDecoder</b>
-attribute holding a reference to type decoder object. Refer to the source
-for API details.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/constraints.html
+++ /dev/null
@@ -1,436 +0,0 @@
-<html>
-<title>
-PyASN1 subtype constraints
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h4>
-1.4 PyASN1 subtype constraints
-</h4>
-
-<p>
-Most ASN.1 types can correspond to an infinite set of values. To adapt to
-particular application's data model and needs, ASN.1 provides a mechanism
-for limiting the infinite set to values, that make sense in particular case.
-</p>
-
-<p>
-Imposing value constraints on an ASN.1 type can also be seen as creating
-a subtype from its base type.
-</p>
-
-<p>
-In pyasn1, constraints take shape of immutable objects capable
-of evaluating given value against constraint-specific requirements.
-Constraint object is a property of pyasn1 type. Like TagSet property,
-associated with every pyasn1 type, constraints can never be modified
-in place. The only way to modify pyasn1 type constraint is to associate
-new constraint object to a new pyasn1 type object.
-</p>
-
-<p>
-A handful of different flavors of <i>constraints</i> are defined in ASN.1.
-We will discuss them one by one in the following chapters and also explain
-how to combine and apply them to types.
-</p>
-
-<a name="1.4.1"></a>
-<h4>
-1.4.1 Single value constraint
-</h4>
-
-<p>
-This kind of constraint allows for limiting type to a finite, specified set
-of values.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-DialButton ::= OCTET STRING (
-  "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-)
-</pre>
-</td></tr></table>
-
-<p>
-Its pyasn1 implementation would look like:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import constraint
->>> c = constraint.SingleValueConstraint(
-  '0','1','2','3','4','5','6','7','8','9'
-)
->>> c
-SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
->>> c('0')
->>> c('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError: 
-  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the snippet above, if a value violates the constraint, an
-exception will be thrown. A constrainted pyasn1 type object holds a
-reference to a constraint object (or their combination, as will be explained
-later) and calls it for value verification.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class DialButton(univ.OctetString):
-...   subtypeSpec = constraint.SingleValueConstraint(
-...       '0','1','2','3','4','5','6','7','8','9'
-...   )
->>> DialButton('0')
-DialButton(b'0')
->>> DialButton('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Constrained pyasn1 value object can never hold a violating value.
-</p>
-
-<a name="1.4.2"></a>
-<h4>
-1.4.2 Value range constraint
-</h4>
-
-<p>
-A pair of values, compliant to a type to be constrained, denote low and upper
-bounds of allowed range of values of a type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Teenagers ::= INTEGER (13..19)
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1 terms:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class Teenagers(univ.Integer):
-...   subtypeSpec = constraint.ValueRangeConstraint(13, 19)
->>> Teenagers(14)
-Teenagers(14)
->>> Teenagers(20)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueRangeConstraint(13, 19) failed at: 20
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Value range constraint usually applies numeric types.
-</p>
-
-<a name="1.4.3"></a>
-<h4>
-1.4.3 Size constraint
-</h4>
-
-<p>
-It is sometimes convenient to set or limit the allowed size of a data item
-to be sent from one application to another to manage bandwidth and memory
-consumption issues. Size constraint specifies the lower and upper bounds 
-of the size of a valid value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-TwoBits ::= BIT STRING (SIZE (2))
-</pre>
-</td></tr></table>
-
-<p>
-Express the same grammar in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class TwoBits(univ.BitString):
-...   subtypeSpec = constraint.ValueSizeConstraint(2, 2)
->>> TwoBits((1,1))
-TwoBits("'11'B")
->>> TwoBits((1,1,0))
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Size constraint can be applied to potentially massive values - bit or octet
-strings, SEQUENCE OF/SET OF values.
-</p>
-
-<a name="1.4.4"></a>
-<h4>
-1.4.4 Alphabet constraint
-</h4>
-
-<p>
-The permitted alphabet constraint is similar to Single value constraint
-but constraint applies to individual characters of a value. 
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MorseCode ::= PrintableString (FROM ("."|"-"|" "))
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class MorseCode(char.PrintableString):
-...   subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
->>> MorseCode("...---...")
-MorseCode('...---...')
->>> MorseCode("?")
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Current implementation does not handle ranges of characters in constraint
-(FROM "A".."Z" syntax), one has to list the whole set in a range.
-</p>
-
-<a name="1.4.5"></a>
-<h4>
-1.4.5 Constraint combinations
-</h4>
-
-<p>
-Up to this moment, we used a single constraint per ASN.1 type. The standard,
-however, allows for combining multiple individual constraints into
-intersections, unions and exclusions.
-</p>
-
-<p>
-In pyasn1 data model, all of these methods of constraint combinations are
-implemented as constraint-like objects holding individual constraint (or
-combination) objects. Like terminal constraint objects, combination objects
-are capable to perform value verification at its set of enclosed constraints
-according to the logic of particular combination.
-</p>
-
-<p>
-Constraints intersection verification succeeds only if a value is
-compliant to each constraint in a set. To begin with, the following
-specification will constitute a valid telephone number:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
-</pre>
-</td></tr></table>
-
-<p>
-Constraint intersection object serves the logic above:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class PhoneNumber(char.NumericString):
-...   subtypeSpec = constraint.ConstraintsIntersection(
-...     constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-...     constraint.ValueSizeConstraint(11, 11)
-...   )
->>> PhoneNumber('79039343212')
-PhoneNumber('79039343212')
->>> PhoneNumber('?9039343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsIntersection(
-    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-      ValueSizeConstraint(11, 11)) failed at: 
-   PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
->>> PhoneNumber('9343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsIntersection(
-    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-      ValueSizeConstraint(11, 11)) failed at:
-  ValueSizeConstraint(10, 10) failed at: "9343212"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Union of constraints works by making sure that a value is compliant
-to any of the constraint in a set. For instance:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
-</pre>
-</td></tr></table>
-
-<p>
-It's important to note, that a value must fully comply to any single
-constraint in a set. In the specification above, a value of all small or
-all capital letters is compliant, but a mix of small&capitals is not. 
-Here's its pyasn1 analogue:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class CapitalOrSmall(char.IA5String):
-...   subtypeSpec = constraint.ConstraintsUnion(
-...     constraint.PermittedAlphabetConstraint('A','B','C'),
-...     constraint.PermittedAlphabetConstraint('a','b','c')
-...   )
->>> CapitalOrSmall('ABBA')
-CapitalOrSmall('ABBA')
->>> CapitalOrSmall('abba')
-CapitalOrSmall('abba')
->>> CapitalOrSmall('Abba')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'),
-    PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Finally, the exclusion constraint simply negates the logic of value 
-verification at a constraint. In the following example, any integer value
-is allowed in a type but not zero.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-NoZero ::= INTEGER (ALL EXCEPT 0)
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 the above definition would read:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class NoZero(univ.Integer):
-...   subtypeSpec = constraint.ConstraintsExclusion(
-...     constraint.SingleValueConstraint(0)
-...   )
->>> NoZero(1)
-NoZero(1)
->>> NoZero(0)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The depth of such a constraints tree, built with constraint combination objects
-at its nodes, has not explicit limit. Value verification is performed in a
-recursive manner till a definite solution is found.
-</p>
-
-<a name="1.5"></a>
-<h4>
-1.5 Types relationships
-</h4>
-
-<p>
-In the course of data processing in an application, it is sometimes
-convenient to figure out the type relationships between pyasn1 type or
-value objects. Formally, two things influence pyasn1 types relationship:
-<i>tag set</i> and <i>subtype constraints</i>. One pyasn1 type is considered
-to be a derivative of another if their TagSet and Constraint objects are
-a derivation of one another.
-</p>
-
-<p>
-The following example illustrates the concept (we use the same tagset but
-different constraints for simplicity):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
->>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
-...    constraint.ValueRangeConstraint(3,8),
-...    constraint.ValueRangeConstraint(4,7)
-... ) )
->>> i1.isSameTypeWith(i2)
-False
->>> i1.isSuperTypeOf(i2)
-True
->>> i1.isSuperTypeOf(i1)
-True
->>> i2.isSuperTypeOf(i1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the above code snippet, there are two methods of any pyasn1
-type/value object that test types for their relationship:
-<b>isSameTypeWith</b>() and <b>isSuperTypeOf</b>(). The former is 
-self-descriptive while the latter yields true if the argument appears
-to be a pyasn1 object which has tagset and constraints derived from those
-of the object being called.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/constructed.html
+++ /dev/null
@@ -1,377 +0,0 @@
-<html>
-<title>
-PyASN1 Constructed types
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h4>
-1.3 PyASN1 Constructed types
-</h4>
-
-<p>
-Besides scalar types, ASN.1 specifies so-called constructed ones - these
-are capable of holding one or more values of other types, both scalar
-and constructed.
-</p>
-
-<p>
-In pyasn1 implementation, constructed ASN.1 types behave like 
-Python sequences, and also support additional component addressing methods,
-specific to particular constructed type.
-</p>
-
-<a name="1.3.1"></a>
-<h4>
-1.3.1 Sequence and Set types
-</h4>
-
-<p>
-The Sequence and Set types have many similar properties:
-</p>
-<ul>
-<li>they can hold any number of inner components of different types
-<li>every component has a human-friendly identifier
-<li>any component can have a default value
-<li>some components can be absent.
-</ul>
-
-<p>
-However, Sequence type guarantees the ordering of Sequence value components
-to match their declaration order. By contrast, components of the
-Set type can be ordered to best suite application's needs.
-<p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Record ::= SEQUENCE {
-  id        INTEGER,
-  room  [0] INTEGER OPTIONAL,
-  house [1] INTEGER DEFAULT 0
-}
-</pre>
-</td></tr></table>
-
-<p>
-Up to this moment, the only method we used for creating new pyasn1 types
-is Python sub-classing. With this method, a new, named Python class is created
-what mimics type derivation in ASN.1 grammar. However, ASN.1 also allows for
-defining anonymous subtypes (room and house components in the example above).
-To support anonymous subtyping in pyasn1, a cloning operation on an existing
-pyasn1 type object can be invoked what creates a new instance of original
-object with possibly modified properties.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Record(univ.Sequence):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('id', univ.Integer()),
-...     namedtype.OptionalNamedType(
-...       'room',
-...       univ.Integer().subtype(
-...         implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
-...       )
-...     ),
-...     namedtype.DefaultedNamedType(
-...       'house', 
-...       univ.Integer(0).subtype(
-...         implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
-...       )
-...     )
-...   )
->>>
-</pre>
-</td></tr></table>
-
-<p>
-All pyasn1 constructed type classes have a class attribute <b>componentType</b>
-that represent default type specification. Its value is a NamedTypes object.
-</p>
-
-<p>
-The NamedTypes class instance holds a sequence of NameType, OptionalNamedType
-or DefaultedNamedType objects which, in turn, refer to pyasn1 type objects that
-represent inner SEQUENCE components specification.
-</p>
-
-<p>
-Finally, invocation of a subtype() method of pyasn1 type objects in the code
-above returns an implicitly tagged copy of original object.
-</p>
-
-<p>
-Once a SEQUENCE or SET type is decleared with pyasn1, it can be instantiated
-and initialized (continuing the above code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record = Record()
->>> record.setComponentByName('id', 123)
->>> print(record.prettyPrint())
-Record:
- id=123
->>> 
->>> record.setComponentByPosition(1, 321)
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
->>>
->>> record.setDefaultComponents()
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
- house=0
-</pre>
-</td></tr></table>
-
-<p>
-Inner components of pyasn1 Sequence/Set objects could be accessed using the
-following methods:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record.getComponentByName('id')
-Integer(123)
->>> record.getComponentByPosition(1)
-Integer(321)
->>> record[2]
-Integer(0)
->>> for idx in range(len(record)):
-...   print(record.getNameByPosition(idx), record.getComponentByPosition(idx))
-id 123
-room 321
-house 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The Set type share all the properties of Sequence type, and additionally
-support by-tag component addressing (as all Set components have distinct
-types).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Gamer(univ.Set):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('score', univ.Integer()),
-...     namedtype.NamedType('player', univ.OctetString()),
-...     namedtype.NamedType('id', univ.ObjectIdentifier())
-...   )
->>> gamer = Gamer()
->>> gamer.setComponentByType(univ.Integer().getTagSet(), 121343)
->>> gamer.setComponentByType(univ.OctetString().getTagSet(), 'Pascal')
->>> gamer.setComponentByType(univ.ObjectIdentifier().getTagSet(), (1,3,7,2))
->>> print(gamer.prettyPrint())
-Gamer:
- score=121343
- player=b'Pascal'
- id=1.3.7.2
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.2"></a>
-<h4>
-1.3.2 SequenceOf and SetOf types
-</h4>
-
-<p>
-Both, SequenceOf and SetOf types resemble an unlimited size list of components.
-All the components must be of the same type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Progression ::= SEQUENCE OF INTEGER
-
-arithmeticProgression Progression ::= { 1, 3, 5, 7 }
-</pre>
-</td></tr></table>
-
-<p>
-SequenceOf and SetOf types are expressed by the very similar pyasn1 type 
-objects. Their components can only be addressed by position and they
-both have a property of automatic resize.
-</p>
-
-<p>
-To specify inner component type, the <b>componentType</b> class attribute
-should refer to another pyasn1 type object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class Progression(univ.SequenceOf):
-...   componentType = univ.Integer()
->>> arithmeticProgression = Progression()
->>> arithmeticProgression.setComponentByPosition(1, 111)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
--empty- 111
->>> arithmeticProgression.setComponentByPosition(0, 100)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
-100 111
->>>
->>> for idx in range(len(arithmeticProgression)):
-...    arithmeticProgression.getComponentByPosition(idx)
-Integer(100)
-Integer(111)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Any scalar or constructed pyasn1 type object can serve as an inner component.
-Missing components are prohibited in SequenceOf/SetOf value objects.
-</p>
-
-<a name="1.3.3"></a>
-<h4>
-1.3.3 Choice type
-</h4>
-
-<p>
-Values of ASN.1 CHOICE type can contain only a single value of a type from a 
-list of possible alternatives. Alternatives must be ASN.1 types with
-distinct tags for the whole structure to remain unambiguous. Unlike most
-other types, CHOICE is an untagged one, e.g. it has no base tag of its own.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CodeOrMessage ::= CHOICE {
-  code    INTEGER,
-  message OCTET STRING
-}
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 implementation, Choice object behaves like Set but accepts only
-a single inner component at a time. It also offers a few additional methods
-specific to its behaviour.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('code', univ.Integer()),
-...     namedtype.NamedType('message', univ.OctetString())
-...   )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
->>> codeOrMessage.setComponentByName('code', 123)
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- code=123
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Since there could be only a single inner component value in the pyasn1 Choice
-value object, either of the following methods could be used for fetching it
-(continuing previous code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> codeOrMessage.getName()
-'message'
->>> codeOrMessage.getComponent()
-OctetString(b'my string value')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.4"></a>
-<h4>
-1.3.4 Any type
-</h4>
-
-<p>
-The ASN.1 ANY type is a kind of wildcard or placeholder that matches
-any other type without knowing it in advance. Like CHOICE type, ANY
-has no base tag.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Error ::= SEQUENCE {
-  code      INTEGER,
-  parameter ANY DEFINED BY code
-}
-</pre>
-</td></tr></table>
-
-<p>
-The ANY type is frequently used in specifications, where exact type is not
-yet agreed upon between communicating parties or the number of possible
-alternatives of a type is infinite.
-Sometimes an auxiliary selector is kept around to help parties indicate
-the kind of ANY payload in effect ("code" in the example above).
-</p>
-
-<p>
-Values of the ANY type contain serialized ASN.1 value(s) in form of
-an octet string. Therefore pyasn1 Any value object share the properties of
-pyasn1 OctetString object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> someValue = univ.Any(b'\x02\x01\x01')
->>> someValue
-Any(b'\x02\x01\x01')
->>> str(someValue)
-'\x02\x01\x01'
->>> bytes(someValue)
-b'\x02\x01\x01'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Receiving application is supposed to explicitly deserialize the content of Any
-value object, possibly using auxiliary selector for figuring out its ASN.1
-type to pick appropriate decoder.
-</p>
-
-<p>
-There will be some more talk and code snippets covering Any type in the codecs
-chapters that follow.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/intro.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<html>
-<title>
-PyASN1 reference manual
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-PyASN1 reference manual
-</h3>
-
-<p align=right>
-<i>written by <a href=mailto:ilya@glas.net>Ilya Etingof</a>, 2011-2012</i>
-</p>
-
-<p>
-Free and open-source pyasn1 library makes it easier for programmers and
-network engineers to develop, debug and experiment with ASN.1-based protocols
-using Python programming language as a tool.
-</p>
-
-<p>
-Abstract Syntax Notation One 
-(<a href=http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>ASN.1</a>)
-is a set of 
-<a href=http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>
-ITU standards</a> concered with provisioning instrumentation for developing
-data exchange protocols in a robust, clear and interoperabable way for
-various IT systems and applications. Most of the efforts are targeting the
-following areas:
-<ul>
-<li>Data structures: the standard introduces a collection of basic data types
-(similar to integers, bits, strings, arrays and records in a programming
-language) that can be used for defining complex, possibly nested data
-structures representing domain-specific data units.
-<li>Serialization protocols: domain-specific data units expressed in ASN.1
-types could be converted into a series of octets for storage or transmission
-over the wire and then recovered back into their structured form on the
-receiving end. This process is immune to various hardware and software
-related dependencies.
-<li>Data description language: could be used to describe particular set of
-domain-specific data structures and their relationships. Such a description
-could be passed to an ASN.1 compiler for automated generation of program
-code that represents ASN.1 data structures in language-native environment
-and handles data serialization issues.
-</ul>
-</p>
-
-<p>
-This tutorial and algorithms, implemented by pyasn1 library, are
-largely based on the information read in the book
-<a href="http://www.oss.com/asn1/dubuisson.html">
-ASN.1 - Communication between heterogeneous systems</a>
-by Olivier Dubuisson. Another relevant resource is
-<a href=ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>
-A Layman's Guide to a Subset of ASN.1, BER, and DER</a> by Burton S. Kaliski.
-It's advised to refer to these books for more in-depth knowledge on the
-subject of ASN.1.
-</p>
-
-<p>
-As of this writing, pyasn1 library implements most of standard ASN.1 data
-structures in a rather detailed and feature-rich manner. Another highly
-important capability of the library is its data serialization facilities.
-The last component of the standard - ASN.1 compiler is planned for
-implementation in the future.
-</p>
-
-</p>
-The pyasn1 library was designed to follow the pre-1995 ASN.1 specification
-(also known as X.208). Later, post 1995, revision (X.680) introduced
-significant changes most of which have not yet been supported by pyasn1.
-</p>
-
-<h3>
-Table of contents
-</h3>
-
-<p>
-<ul>
-<li><a href="scalar.html">1. Data model for ASN.1 types</a>
-<li><a href="scalar.html#1.1">1.1 Scalar types</a>
-<li><a href="scalar.html#1.1.1">1.1.1 Boolean type</a>
-<li><a href="scalar.html#1.1.2">1.1.2 Null type</a>
-<li><a href="scalar.html#1.1.3">1.1.3 Integer type</a>
-<li><a href="scalar.html#1.1.4">1.1.4 Enumerated type</a>
-<li><a href="scalar.html#1.1.5">1.1.5 Real type</a>
-<li><a href="scalar.html#1.1.6">1.1.6 Bit string type</a>
-<li><a href="scalar.html#1.1.7">1.1.7 OctetString type</a>
-<li><a href="scalar.html#1.1.8">1.1.8 ObjectIdentifier type</a>
-<li><a href="scalar.html#1.1.9">1.1.9 Character string types</a>
-<li><a href="scalar.html#1.1.10">1.1.10 Useful types</a>
-<li><a href="tagging.html">1.2 Tagging</a>
-<li><a href="constructed.html">1.3 Constructed types</a>
-<li><a href="constructed.html#1.3.1">1.3.1 Sequence and Set types</a>
-<li><a href="constructed.html#1.3.2">1.3.2 SequenceOf and SetOf types</a>
-<li><a href="constructed.html#1.3.3">1.3.3 Choice type</a>
-<li><a href="constructed.html#1.3.4">1.3.4 Any type</a>
-<li><a href="constraints.html">1.4 Subtype constraints</a>
-<li><a href="constraints.html#1.4.1">1.4.1 Single value constraint</a>
-<li><a href="constraints.html#1.4.2">1.4.2 Value range constraint</a>
-<li><a href="constraints.html#1.4.3">1.4.3 Size constraint</a>
-<li><a href="constraints.html#1.4.4">1.4.4 Alphabet constraint</a>
-<li><a href="constraints.html#1.4.5">1.4.5 Constraint combinations</a>
-<li><a href="constraints.html#1.5">1.5 Types relationships</a>
-<li><a href="codecs.html">2. Codecs</a>
-<li><a href="codecs.html#2.1">2.1 Encoders</a>
-<li><a href="codecs.html#2.2">2.2 Decoders</a>
-<li><a href="codecs.html#2.2.1">2.2.1 Decoding untagged types</a>
-<li><a href="codecs.html#2.2.2">2.2.2 Ignoring unknown types</a>
-</ul>
-
-<p>
-Although pyasn1 software is almost a decade old and used in many production
-environments, it still may have bugs and non-implemented pieces. Anyone
-who happens to run into such defect is welcome to complain to
-<a href=mailto:pyasn1-users@lists.sourceforge.net>pyasn1 mailing list</a>
-or better yet fix the issue and send
-<a href=mailto:ilya@glas.net>me</a> the patch.
-</p>
-
-<p>
-Typically, pyasn1 is used for building arbitrary protocol support into
-various applications. This involves manual translation of ASN.1 data
-structures into their pyasn1 implementations. To save time and effort,
-data structures for some of the popular protocols are pre-programmed
-and kept for further re-use in form of the
-<a href=http://sourceforge.net/projects/pyasn1/files/pyasn1-modules/>
-pyasn1-modules package</a>. For instance, many structures for PKI (X.509,
-PKCS#*, CRMF, OCSP), LDAP and SNMP are present.
-Applications authors are advised to import and use relevant modules 
-from that package whenever needed protocol structures are already 
-there. New protocol modules contributions are welcome.
-</p>
-
-<p>
-And finally, the latest pyasn1 package revision is available for free
-download from
-<a href=http://sourceforge.net/projects/pyasn1/>project home</a> and
-also from the 
-<a href=http://pypi.python.org/pypi>Python package repository</a>.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/pyasn1-tutorial.html
+++ /dev/null
@@ -1,2405 +0,0 @@
-<html>
-<title>
-PyASN1 programmer's manual
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-PyASN1 programmer's manual
-</h3>
-
-<p align=right>
-<i>written by <a href=mailto:ilya@glas.net>Ilya Etingof</a>, 2011-2012</i>
-</p>
-
-<p>
-Free and open-source pyasn1 library makes it easier for programmers and
-network engineers to develop, debug and experiment with ASN.1-based protocols
-using Python programming language as a tool.
-</p>
-
-<p>
-Abstract Syntax Notation One 
-(<a href=http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>ASN.1</a>)
-is a set of 
-<a href=http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>
-ITU standards</a> concered with provisioning instrumentation for developing
-data exchange protocols in a robust, clear and interoperabable way for
-various IT systems and applications. Most of the efforts are targeting the
-following areas:
-<ul>
-<li>Data structures: the standard introduces a collection of basic data types
-(similar to integers, bits, strings, arrays and records in a programming
-language) that can be used for defining complex, possibly nested data
-structures representing domain-specific data units.
-<li>Serialization protocols: domain-specific data units expressed in ASN.1
-types could be converted into a series of octets for storage or transmission
-over the wire and then recovered back into their structured form on the
-receiving end. This process is immune to various hardware and software
-related dependencies.
-<li>Data description language: could be used to describe particular set of
-domain-specific data structures and their relationships. Such a description
-could be passed to an ASN.1 compiler for automated generation of program
-code that represents ASN.1 data structures in language-native environment
-and handles data serialization issues.
-</ul>
-</p>
-
-<p>
-This tutorial and algorithms, implemented by pyasn1 library, are
-largely based on the information read in the book
-<a href="http://www.oss.com/asn1/dubuisson.html">
-ASN.1 - Communication between heterogeneous systems</a>
-by Olivier Dubuisson. Another relevant resource is
-<a href=ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>
-A Layman's Guide to a Subset of ASN.1, BER, and DER</a> by Burton S. Kaliski.
-It's advised to refer to these books for more in-depth knowledge on the
-subject of ASN.1.
-</p>
-
-<p>
-As of this writing, pyasn1 library implements most of standard ASN.1 data
-structures in a rather detailed and feature-rich manner. Another highly
-important capability of the library is its data serialization facilities.
-The last component of the standard - ASN.1 compiler is planned for
-implementation in the future.
-</p>
-
-</p>
-The pyasn1 library was designed to follow the pre-1995 ASN.1 specification
-(also known as X.208). Later, post 1995, revision (X.680) introduced
-significant changes most of which have not yet been supported by pyasn1.
-</p>
-
-<h3>
-Table of contents
-</h3>
-
-<p>
-<ul>
-<li><a href="#1">1. Data model for ASN.1 types</a>
-<li><a href="#1.1">1.1 Scalar types</a>
-<li><a href="#1.1.1">1.1.1 Boolean type</a>
-<li><a href="#1.1.2">1.1.2 Null type</a>
-<li><a href="#1.1.3">1.1.3 Integer type</a>
-<li><a href="#1.1.4">1.1.4 Enumerated type</a>
-<li><a href="#1.1.5">1.1.5 Real type</a>
-<li><a href="#1.1.6">1.1.6 Bit string type</a>
-<li><a href="#1.1.7">1.1.7 OctetString type</a>
-<li><a href="#1.1.8">1.1.8 ObjectIdentifier type</a>
-<li><a href="#1.1.9">1.1.9 Character string types</a>
-<li><a href="#1.1.10">1.1.10 Useful types</a>
-<li><a href="#1.2">1.2 Tagging</a>
-<li><a href="#1.3">1.3 Constructed types</a>
-<li><a href="#1.3.1">1.3.1 Sequence and Set types</a>
-<li><a href="#1.3.2">1.3.2 SequenceOf and SetOf types</a>
-<li><a href="#1.3.3">1.3.3 Choice type</a>
-<li><a href="#1.3.4">1.3.4 Any type</a>
-<li><a href="#1.4">1.4 Subtype constraints</a>
-<li><a href="#1.4.1">1.4.1 Single value constraint</a>
-<li><a href="#1.4.2">1.4.2 Value range constraint</a>
-<li><a href="#1.4.3">1.4.3 Size constraint</a>
-<li><a href="#1.4.4">1.4.4 Alphabet constraint</a>
-<li><a href="#1.4.5">1.4.5 Constraint combinations</a>
-<li><a href="#1.5">1.5 Types relationships</a>
-<li><a href="#2">2. Codecs</a>
-<li><a href="#2.1">2.1 Encoders</a>
-<li><a href="#2.2">2.2 Decoders</a>
-<li><a href="#2.2.1">2.2.1 Decoding untagged types</a>
-<li><a href="#2.2.2">2.2.2 Ignoring unknown types</a>
-<li><a href="#3">3. Feedback and getting help</a>
-</ul>
-
-
-<a name="1"></a>
-<h3>
-1. Data model for ASN.1 types
-</h3>
-
-<p>
-All ASN.1 types could be categorized into two groups: scalar (also called
-simple or primitive) and constructed. The first group is populated by
-well-known types like Integer or String. Members of constructed group
-hold other types (simple or constructed) as their inner components, thus
-they are semantically close to a programming language records or lists.
-</p>
-
-<p>
-In pyasn1, all ASN.1 types and values are implemented as Python objects.
-The same pyasn1 object can represent either ASN.1 type and/or value
-depending of the presense of value initializer on object instantiation.
-We will further refer to these as <i>pyasn1 type object</i> versus <i>pyasn1
-value object</i>.
-</p>
-
-<p>
-Primitive ASN.1 types are implemented as immutable scalar objects. There values
-could be used just like corresponding native Python values (integers,
-strings/bytes etc) and freely mixed with them in expressions.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerValue = univ.Integer(12)
->>> asn1IntegerValue - 2
-10
->>> univ.OctetString('abc') == 'abc'
-True   # Python 2
->>> univ.OctetString(b'abc') == b'abc'
-True   # Python 3
-</pre>
-</td></tr></table>
-
-<p>
-It would be an error to perform an operation on a pyasn1 type object
-as it holds no value to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerType = univ.Integer()
->>> asn1IntegerType - 2
-...
-pyasn1.error.PyAsn1Error: No value for __coerce__()
-</pre>
-</td></tr></table>
-
-<a name="1.1"></a>
-<h4>
-1.1 Scalar types
-</h4>
-
-<p>
-In the sub-sections that follow we will explain pyasn1 mapping to those
-primitive ASN.1 types. Both, ASN.1 notation and corresponding pyasn1
-syntax will be given in each case.
-</p>
-
-<a name="1.1.1"></a>
-<h4>
-1.1.1 Boolean type
-</h4>
-
-<p>
-This is the simplest type those values could be either True or False.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-FunFactorPresent ::= BOOLEAN
-
-;; values declaration and assignment
-pythonFunFactor FunFactorPresent ::= TRUE
-cobolFunFactor FunFactorPresent :: FALSE
-</pre>
-</td></tr></table>
-
-<p>
-And here's pyasn1 version of it:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class FunFactorPresent(univ.Boolean): pass
-... 
->>> pythonFunFactor = FunFactorPresent(True)
->>> cobolFunFactor = FunFactorPresent(False)
->>> pythonFunFactor
-FunFactorPresent('True(1)')
->>> cobolFunFactor
-FunFactorPresent('False(0)')
->>> pythonFunFactor == cobolFunFactor
-False
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.2"></a>
-<h4>
-1.1.2 Null type
-</h4>
-
-<p>
-The NULL type is sometimes used to express the absense of any information.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-Vote ::= CHOICE {
-  agreed BOOLEAN,
-  skip NULL
-}
-</td></tr></table>
-
-;; value declaration and assignment
-myVote Vote ::= skip:NULL
-</pre>
-
-<p>
-We will explain the CHOICE type later in this paper, meanwhile the NULL
-type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> skip = univ.Null()
->>> skip
-Null('')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.3"></a>
-<h4>
-1.1.3 Integer type
-</h4>
-
-<p>
-ASN.1 defines the values of Integer type as negative or positive of whatever
-length. This definition plays nicely with Python as the latter places no
-limit on Integers. However, some ASN.1 implementations may impose certain
-limits of integer value ranges. Keep that in mind when designing new
-data structures.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; values specification
-age-of-universe INTEGER ::= 13750000000
-mean-martian-surface-temperature INTEGER ::= -63
-</pre>
-</td></tr></table>
-
-<p>
-A rather strigntforward mapping into pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> ageOfUniverse = univ.Integer(13750000000)
->>> ageOfUniverse
-Integer(13750000000)
->>>
->>> meanMartianSurfaceTemperature = univ.Integer(-63)
->>> meanMartianSurfaceTemperature
-Integer(-63)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-ASN.1 allows to assign human-friendly names to particular values of
-an INTEGER type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Temperature ::= INTEGER {
-  freezing(0),
-  boiling(100) 
-}
-</pre>
-</td></tr></table>
-
-<p>
-The Temperature type expressed in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class Temperature(univ.Integer):
-...   namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
-...
->>> t = Temperature(0)
->>> t
-Temperature('freezing(0)')
->>> t + 1
-Temperature(1)
->>> t + 100
-Temperature('boiling(100)')
->>> t = Temperature('boiling')
->>> t
-Temperature('boiling(100)')
->>> Temperature('boiling') / 2
-Temperature(50)
->>> -1 < Temperature('freezing')
-True
->>> 47 > Temperature('boiling')
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-These values labels have no effect on Integer type operations, any value
-still could be assigned to a type (information on value constraints will
-follow further in this paper).
-</p>
-
-<a name="1.1.4"></a>
-<h4>
-1.1.4 Enumerated type
-</h4>
-
-<p>
-ASN.1 Enumerated type differs from an Integer type in a number of ways.
-Most important is that its instance can only hold a value that belongs
-to a set of values specified on type declaration.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-error-status ::= ENUMERATED {
-  no-error(0),
-  authentication-error(10),
-  authorization-error(20),
-  general-failure(51)
-}
-</pre>
-</td></tr></table>
-
-<p>
-When constructing Enumerated type we will use two pyasn1 features: values
-labels (as mentioned above) and value constraint (will be described in
-more details later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval, constraint
->>> class ErrorStatus(univ.Enumerated):
-...   namedValues = namedval.NamedValues(
-...        ('no-error', 0),
-...        ('authentication-error', 10),
-...        ('authorization-error', 20),
-...        ('general-failure', 51)
-...   )
-...   subtypeSpec = univ.Enumerated.subtypeSpec + \
-...                    constraint.SingleValueConstraint(0, 10, 20, 51)
-...
->>> errorStatus = univ.ErrorStatus('no-error')
->>> errorStatus
-ErrorStatus('no-error(0)')
->>> errorStatus == univ.ErrorStatus('general-failure')
-False
->>> univ.ErrorStatus('non-existing-state')
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Particular integer values associated with Enumerated value states
-have no meaning. They should not be used as such or in any kind of
-math operation. Those integer values are only used by codecs to
-transfer state from one entity to another.
-</p>
-
-<a name="1.1.5"></a>
-<h4>
-1.1.5 Real type
-</h4>
-
-<p>
-Values of the Real type are a three-component tuple of mantissa, base and 
-exponent. All three are integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-pi ::= REAL { mantissa 314159, base 10, exponent -5 }
-</pre>
-</td></tr></table>
-
-<p>
-Corresponding pyasn1 objects can be initialized with either a three-component
-tuple or a Python float. Infinite values could be expressed in a way, 
-compatible with Python float type.
-
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> pi = univ.Real((314159, 10, -5))
->>> pi
-Real((314159, 10,-5))
->>> float(pi)
-3.14159
->>> pi == univ.Real(3.14159)
-True
->>> univ.Real('inf')
-Real('inf')
->>> univ.Real('-inf') == float('-inf')
-True
->>>
-</pre>
-</td></tr></table>
-
-<p>
-If a Real object is initialized from a Python float or yielded by a math
-operation, the base is set to decimal 10 (what affects encoding).
-</p>
-
-<a name="1.1.6"></a>
-<h4>
-1.1.6 Bit string type
-</h4>
-
-<p>
-ASN.1 BIT STRING type holds opaque binary data of an arbitrarily length.
-A BIT STRING value could be initialized by either a binary (base 2) or 
-hex (base 16) value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-public-key BIT STRING ::= '1010111011110001010110101101101
-                           1011000101010000010110101100010
-                           0110101010000111101010111111110'B
-
-signature  BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
-</pre>
-</td></tr></table>
-
-<p>
-The pyasn1 BitString objects can initialize from native ASN.1 notation
-(base 2 or base 16 strings) or from a Python tuple of binary components.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> publicKey = univ.BitString(
-...          "'1010111011110001010110101101101"
-...          "1011000101010000010110101100010"
-...          "0110101010000111101010111111110'B"
-)
->>> publicKey
-BitString("'10101110111100010101101011011011011000101010000010110101100010\
-0110101010000111101010111111110'B")
->>> signature = univ.BitString(
-...          "'AF01330CD932093392100B39FF00DE0'H"
-... )
->>> signature
-BitString("'101011110000000100110011000011001101100100110010000010010011001\
-1100100100001000000001011001110011111111100000000110111100000'B")
->>> fingerprint = univ.BitString(
-...          (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
-... )
->>> fingerprint
-BitString("'101101110101'B")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Another BIT STRING initialization method supported by ASN.1 notation
-is to specify only 1-th bits along with their human-friendly label
-and bit offset relative to the beginning of the bit string. With this 
-method, all not explicitly mentioned bits are doomed to be zeros.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-bit-mask  BIT STRING ::= {
-  read-flag(0),
-  write-flag(2),
-  run-flag(4)
-}
-</pre>
-</td></tr></table>
-
-<p>
-To express this in pyasn1, we will employ the named values feature (as with
-Enumeration type).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class BitMask(univ.BitString):
-...   namedValues = namedval.NamedValues(
-...        ('read-flag', 0),
-...        ('write-flag', 2),
-...        ('run-flag', 4)
-... )
->>> bitMask = BitMask('read-flag,run-flag')
->>> bitMask
-BitMask("'10001'B")
->>> tuple(bitMask)
-(1, 0, 0, 0, 1)
->>> bitMask[4]
-1
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The BitString objects mimic the properties of Python tuple type in part
-of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.7"></a>
-<h4>
-1.1.7 OctetString type
-</h4>
-
-<p>
-The OCTET STRING type is a confusing subject. According to ASN.1
-specification, this type is similar to BIT STRING, the major difference
-is that the former operates in 8-bit chunks of data. What is important
-to note, is that OCTET STRING was NOT designed to handle text strings - the
-standard provides many other types specialized for text content. For that
-reason, ASN.1 forbids to initialize OCTET STRING values with "quoted text
-strings", only binary or hex initializers, similar to BIT STRING ones,
-are allowed.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
-thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
-</pre>
-</td></tr></table>
-
-<p>
-However, ASN.1 users (e.g. protocols designers) seem to ignore the original
-purpose of the OCTET STRING type - they used it for handling all kinds of
-data, including text strings.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, we have taken a liberal approach and allowed both BIT STRING
-style and quoted text initializers for the OctetString objects. To avoid
-possible collisions, quoted text is the default initialization syntax.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> thumbnail = univ.OctetString(
-...    binValue='1000010111101110101111000000111011'
-... )
->>> thumbnail
-OctetString(hexValue='85eebcec0')
->>> thumbnail = univ.OctetString(
-...    hexValue='FA9823C43E43510DE3422'
-... )
->>> thumbnail
-OctetString(hexValue='fa9823c43e4351de34220')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Most frequent usage of the OctetString class is to instantiate it with
-a text string.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
->>> welcomeMessage
-OctetString(b'Welcome to ASN.1 wilderness!')
->>> print('%s' % welcomeMessage)
-Welcome to ASN.1 wilderness!
->>> welcomeMessage[11:16]
-OctetString(b'ASN.1')
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-OctetString objects support the immutable sequence object protocol.
-In other words, they behave like Python 3 bytes (or Python 2 strings).
-</p>
-
-<p>
-When running pyasn1 on Python 3, it's better to use the bytes objects for
-OctetString instantiation, as it's more reliable and efficient.
-</p>
-
-<p>
-Additionally, OctetString's can also be instantiated with a sequence of
-8-bit integers (ASCII codes).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> univ.OctetString((77, 101, 101, 103, 111))
-OctetString(b'Meego')
-</pre>
-</td></tr></table>
-
-<p>
-It is sometimes convenient to express OctetString instances as 8-bit
-characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> octetString = univ.OctetString('ABCDEF')
->>> octetString.asNumbers()
-(65, 66, 67, 68, 69, 70)
->>> octetString.asOctets()
-b'ABCDEF'
-</pre>
-</td></tr></table>
-
-<a name="1.1.8"></a>
-<h4>
-1.1.8 ObjectIdentifier type
-</h4>
-
-<p>
-Values of the OBJECT IDENTIFIER type are sequences of integers that could
-be used to identify virtually anything in the world. Various ASN.1-based
-protocols employ OBJECT IDENTIFIERs for their own identification needs.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-internet-id OBJECT IDENTIFIER ::= {
-  iso(1) identified-organization(3) dod(6) internet(1)
-}
-</pre>
-</td></tr></table>
-
-<p>
-One of the natural ways to map OBJECT IDENTIFIER type into a Python
-one is to use Python tuples of integers. So this approach is taken by
-pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
->>> internetId
-ObjectIdentifier('1.3.6.1')
->>> internetId[2]
-6
->>> internetId[1:3]
-ObjectIdentifier('3.6')
-</pre>
-</td></tr></table>
-
-<p>
-A more human-friendly "dotted" notation is also supported.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> univ.ObjectIdentifier('1.3.6.1')
-ObjectIdentifier('1.3.6.1')
-</pre>
-</td></tr></table>
-
-<p>
-Symbolic names of the arcs of object identifier, sometimes present in
-ASN.1 specifications, are not preserved and used in pyasn1 objects.
-</p>
-
-<p>
-The ObjectIdentifier objects mimic the properties of Python tuple type in
-part of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.9"></a>
-<h4>
-1.1.9 Character string types
-</h4>
-
-<p>
-ASN.1 standard introduces a diverse set of text-specific types. All of them
-were designed to handle various types of characters. Some of these types seem
-be obsolete nowdays, as their target technologies are gone. Another issue
-to be aware of is that raw OCTET STRING type is sometimes used in practice
-by ASN.1 users instead of specialized character string types, despite
-explicit prohibition imposed by ASN.1 specification.
-</p>
-
-<p>
-The two types are specific to ASN.1 are NumericString and PrintableString.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message ::= PrintableString {
-  "Welcome to ASN.1 text types"
-}
-
-dial-pad-numbers ::= NumericString {
-  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
-}
-</pre>
-</td></tr></table>
-
-<p>
-Their pyasn1 implementations are:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
-'Welcome to ASN.1 text types'
->>> dialPadNumbers = char.NumericString(
-      "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
-)
->>> dialPadNumbers
-NumericString(b'0123456789')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The following types came to ASN.1 from ISO standards on character sets.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.VisibleString("abc")
-VisibleString(b'abc')
->>> char.IA5String('abc')
-IA5String(b'abc')
->>> char.TeletexString('abc')
-TeletexString(b'abc')
->>> char.VideotexString('abc')
-VideotexString(b'abc')
->>> char.GraphicString('abc')
-GraphicString(b'abc')
->>> char.GeneralString('abc')
-GeneralString(b'abc')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The last three types are relatively recent addition to the family of
-character string types: UniversalString, BMPString, UTF8String.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.UniversalString("abc")
-UniversalString(b'abc')
->>> char.BMPString('abc')
-BMPString(b'abc')
->>> char.UTF8String('abc')
-UTF8String(b'abc')
->>> utf8String = char.UTF8String('У попа была собака')
->>> utf8String
-UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0 \
-\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
->>> print(utf8String)
-У попа была собака
->>>
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, all character type objects behave like Python strings. None of
-them is currently constrained in terms of valid alphabet so it's up to
-the data source to keep an eye on data validation for these types.
-</p>
-
-<a name="1.1.10"></a>
-<h4>
-1.1.10 Useful types
-</h4>
-
-<p>
-There are three so-called useful types defined in the standard:
-ObjectDescriptor, GeneralizedTime, UTCTime. They all are subtypes
-of GraphicString or VisibleString types therefore useful types are
-character string types.
-</p>
-
-<p>
-It's advised by the ASN.1 standard to have an instance of ObjectDescriptor
-type holding a human-readable description of corresponding instance of
-OBJECT IDENTIFIER type. There are no formal linkage between these instances
-and provision for ObjectDescriptor uniqueness in the standard.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> descrBER = useful.ObjectDescriptor(
-      "Basic encoding of a single ASN.1 type"
-)
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-GeneralizedTime and UTCTime types are designed to hold a human-readable
-timestamp in a universal and unambiguous form. The former provides
-more flexibility in notation while the latter is more strict but has
-Y2K issues.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; Mar 8 2010 12:00:00 MSK
-moscow-time GeneralizedTime ::= "20110308120000.0"
-;; Mar 8 2010 12:00:00 UTC
-utc-time GeneralizedTime ::= "201103081200Z"
-;; Mar 8 1999 12:00:00 UTC
-utc-time UTCTime ::= "9803081200Z"
-</pre>
-</td></tr></table>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> moscowTime = useful.GeneralizedTime("20110308120000.0")
->>> utcTime = useful.UTCTime("9803081200Z")
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Despite their intended use, these types possess no special, time-related,
-handling in pyasn1. They are just printable strings.
-</p>
-
-<a name="1.2"></a>
-<h4>
-1.2 Tagging
-</h4>
-
-<p>
-In order to continue with the Constructed ASN.1 types, we will first have
-to introduce the concept of tagging (and its pyasn1 implementation), as
-some of the Constructed types rely upon the tagging feature.
-</p>
-
-<p>
-When a value is coming into an ASN.1-based system (received from a network
-or read from some storage), the receiving entity has to determine the
-type of the value to interpret and verify it accordingly.
-</p>
-
-<p>
-Historically, the first data serialization protocol introduced in
-ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
-value is packed into a triplet of (Type, Length, Value) where Type is a 
-code that identifies the value (which is called <i>tag</i> in ASN.1),
-length is the number of bytes occupied by the value in its serialized form
-and value is ASN.1 value in a form suitable for serial transmission or storage.
-</p>
-
-<p>
-For that reason almost every ASN.1 type has a tag (which is actually a
-BER type) associated with it by default.
-</p>
-
-<p>
-An ASN.1 tag could be viewed as a tuple of three numbers:
-(Class, Format, Number). While Number identifies a tag, Class component 
-is used to create scopes for Numbers. Four scopes are currently defined:
-UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
-is actually a one-bit flag - zero for tags associated with scalar types,
-and one for constructed types (will be discussed later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] INTEGER
-MyOctetString ::= [APPLICATION 0] OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, tags are implemented as immutable, tuple-like objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
->>> myTag
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tuple(myTag)
-(128, 0, 10)
->>> myTag[2]
-10
->>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Default tag, associated with any ASN.1 type, could be extended or replaced
-to make new type distinguishable from its ancestor. The standard provides
-two modes of tag mangling - IMPLICIT and EXPLICIT.
-</p>
-
-<p>
-EXPLICIT mode works by appending new tag to the existing ones thus creating
-an ordered set of tags. This set will be considered as a whole for type
-identification and encoding purposes. Important property of EXPLICIT tagging
-mode is that it preserves base type information in encoding what makes it
-possible to completely recover type information from encoding.
-</p>
-
-<p>
-When tagging in IMPLICIT mode, the outermost existing tag is dropped and
-replaced with a new one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] IMPLICIT INTEGER
-MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-To model both modes of tagging, a specialized container TagSet object (holding
-zero, one or more Tag objects) is used in pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet = tag.TagSet(
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10), # base tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)  # effective tag
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10))
->>> tagSet.getBaseTag()
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tagSet = tagSet.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
-       Tag(tagClass=128, tagFormat=32, tagId=20))
->>> tagSet = tagSet.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
-       Tag(tagClass=128, tagFormat=32, tagId=20), 
-       Tag(tagClass=128, tagFormat=32, tagId=30))
->>> tagSet = tagSet.tagImplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
-       Tag(tagClass=128, tagFormat=32, tagId=20),
-       Tag(tagClass=128, tagFormat=32, tagId=40))
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-As a side note: the "base tag" concept (accessible through the getBaseTag()
-method) is specific to pyasn1 -- the base tag is used to identify the original
-ASN.1 type of an object in question. Base tag is never occurs in encoding
-and is mostly used internally by pyasn1 for choosing type-specific data 
-processing algorithms. The "effective tag" is the one that always appears in
-encoding and is used on tagSets comparation.
-</p>
-
-<p>
-Any two TagSet objects could be compared to see if one is a derivative
-of the other. Figuring this out is also useful in cases when a type-specific
-data processing algorithms are to be chosen.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet1 = tag.TagSet(
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10) # base tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10) # effective tag
-... )
->>> tagSet2 = tagSet1.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet1.isSuperTagSetOf(tagSet2)
-True
->>> tagSet2.isSuperTagSetOf(tagSet1)
-False
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-We will complete this discussion on tagging with a real-world example. The
-following ASN.1 tagged type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] EXPLICIT INTEGER
-</pre>
-</td></tr></table>
-
-<p>
-could be expressed in pyasn1 like this:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> class MyIntegerType(univ.Integer):
-...   tagSet = univ.Integer.tagSet.tagExplicitly(
-...        tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12)
-...        )
->>> myInteger = MyIntegerType(12345)
->>> myInteger.getTagSet()
-TagSet(Tag(tagClass=0, tagFormat=0, tagId=2), 
-       Tag(tagClass=128, tagFormat=32, tagId=12))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Referring to the above code, the tagSet class attribute is a property of any
-pyasn1 type object that assigns default tagSet to a pyasn1 value object. This
-default tagSet specification can be ignored and effectively replaced by some
-other tagSet value passed on object instantiation.
-</p>
-
-<p>
-It's important to understand that the tag set property of pyasn1 type/value
-object can never be modifed in place. In other words, a pyasn1 type/value
-object can never change its tags. The only way is to create a new pyasn1
-type/value object and associate different tag set with it.
-</p>
-
-
-<a name="1.3"></a>
-<h4>
-1.3 Constructed types
-</h4>
-
-<p>
-Besides scalar types, ASN.1 specifies so-called constructed ones - these
-are capable of holding one or more values of other types, both scalar
-and constructed.
-</p>
-
-<p>
-In pyasn1 implementation, constructed ASN.1 types behave like 
-Python sequences, and also support additional component addressing methods,
-specific to particular constructed type.
-</p>
-
-<a name="1.3.1"></a>
-<h4>
-1.3.1 Sequence and Set types
-</h4>
-
-<p>
-The Sequence and Set types have many similar properties:
-</p>
-<ul>
-<li>they can hold any number of inner components of different types
-<li>every component has a human-friendly identifier
-<li>any component can have a default value
-<li>some components can be absent.
-</ul>
-
-<p>
-However, Sequence type guarantees the ordering of Sequence value components
-to match their declaration order. By contrast, components of the
-Set type can be ordered to best suite application's needs.
-<p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Record ::= SEQUENCE {
-  id        INTEGER,
-  room  [0] INTEGER OPTIONAL,
-  house [1] INTEGER DEFAULT 0
-}
-</pre>
-</td></tr></table>
-
-<p>
-Up to this moment, the only method we used for creating new pyasn1 types
-is Python sub-classing. With this method, a new, named Python class is created
-what mimics type derivation in ASN.1 grammar. However, ASN.1 also allows for
-defining anonymous subtypes (room and house components in the example above).
-To support anonymous subtyping in pyasn1, a cloning operation on an existing
-pyasn1 type object can be invoked what creates a new instance of original
-object with possibly modified properties.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Record(univ.Sequence):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('id', univ.Integer()),
-...     namedtype.OptionalNamedType(
-...       'room',
-...       univ.Integer().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
-...     ),
-...     namedtype.DefaultedNamedType(
-...       'house', 
-...       univ.Integer(0).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))
-...     )
-...   )
->>>
-</pre>
-</td></tr></table>
-
-<p>
-All pyasn1 constructed type classes have a class attribute <b>componentType</b>
-that represent default type specification. Its value is a NamedTypes object.
-</p>
-
-<p>
-The NamedTypes class instance holds a sequence of NameType, OptionalNamedType
-or DefaultedNamedType objects which, in turn, refer to pyasn1 type objects that
-represent inner SEQUENCE components specification.
-</p>
-
-<p>
-Finally, invocation of a subtype() method of pyasn1 type objects in the code
-above returns an implicitly tagged copy of original object.
-</p>
-
-<p>
-Once a SEQUENCE or SET type is decleared with pyasn1, it can be instantiated
-and initialized (continuing the above code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record = Record()
->>> record.setComponentByName('id', 123)
->>> print(record.prettyPrint())
-Record:
- id=123
->>> 
->>> record.setComponentByPosition(1, 321)
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
->>>
->>> record.setDefaultComponents()
->>> print(record.prettyPrint())
-Record:
- id=123
- room=321
- house=0
-</pre>
-</td></tr></table>
-
-<p>
-Inner components of pyasn1 Sequence/Set objects could be accessed using the
-following methods:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> record.getComponentByName('id')
-Integer(123)
->>> record.getComponentByPosition(1)
-Integer(321)
->>> record[2]
-Integer(0)
->>> for idx in range(len(record)):
-...   print(record.getNameByPosition(idx), record.getComponentByPosition(idx))
-id 123
-room 321
-house 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The Set type share all the properties of Sequence type, and additionally
-support by-tag component addressing (as all Set components have distinct
-types).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype, tag
->>> class Gamer(univ.Set):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('score', univ.Integer()),
-...     namedtype.NamedType('player', univ.OctetString()),
-...     namedtype.NamedType('id', univ.ObjectIdentifier())
-...   )
->>> gamer = Gamer()
->>> gamer.setComponentByType(univ.Integer().getTagSet(), 121343)
->>> gamer.setComponentByType(univ.OctetString().getTagSet(), 'Pascal')
->>> gamer.setComponentByType(univ.ObjectIdentifier().getTagSet(), (1,3,7,2))
->>> print(gamer.prettyPrint())
-Gamer:
- score=121343
- player=b'Pascal'
- id=1.3.7.2
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.2"></a>
-<h4>
-1.3.2 SequenceOf and SetOf types
-</h4>
-
-<p>
-Both, SequenceOf and SetOf types resemble an unlimited size list of components.
-All the components must be of the same type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Progression ::= SEQUENCE OF INTEGER
-
-arithmeticProgression Progression ::= { 1, 3, 5, 7 }
-</pre>
-</td></tr></table>
-
-<p>
-SequenceOf and SetOf types are expressed by the very similar pyasn1 type 
-objects. Their components can only be addressed by position and they
-both have a property of automatic resize.
-</p>
-
-<p>
-To specify inner component type, the <b>componentType</b> class attribute
-should refer to another pyasn1 type object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class Progression(univ.SequenceOf):
-...   componentType = univ.Integer()
->>> arithmeticProgression = Progression()
->>> arithmeticProgression.setComponentByPosition(1, 111)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
--empty- 111
->>> arithmeticProgression.setComponentByPosition(0, 100)
->>> print(arithmeticProgression.prettyPrint())
-Progression:
-100 111
->>>
->>> for idx in range(len(arithmeticProgression)):
-...    arithmeticProgression.getComponentByPosition(idx)
-Integer(100)
-Integer(111)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Any scalar or constructed pyasn1 type object can serve as an inner component.
-Missing components are prohibited in SequenceOf/SetOf value objects.
-</p>
-
-<a name="1.3.3"></a>
-<h4>
-1.3.3 Choice type
-</h4>
-
-<p>
-Values of ASN.1 CHOICE type can contain only a single value of a type from a 
-list of possible alternatives. Alternatives must be ASN.1 types with
-distinct tags for the whole structure to remain unambiguous. Unlike most
-other types, CHOICE is an untagged one, e.g. it has no base tag of its own.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CodeOrMessage ::= CHOICE {
-  code    INTEGER,
-  message OCTET STRING
-}
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 implementation, Choice object behaves like Set but accepts only
-a single inner component at a time. It also offers a few additional methods
-specific to its behaviour.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('code', univ.Integer()),
-...     namedtype.NamedType('message', univ.OctetString())
-...   )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
->>> codeOrMessage.setComponentByName('code', 123)
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- code=123
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Since there could be only a single inner component value in the pyasn1 Choice
-value object, either of the following methods could be used for fetching it
-(continuing previous code):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> codeOrMessage.getName()
-'message'
->>> codeOrMessage.getComponent()
-OctetString(b'my string value')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.3.4"></a>
-<h4>
-1.3.4 Any type
-</h4>
-
-<p>
-The ASN.1 ANY type is a kind of wildcard or placeholder that matches
-any other type without knowing it in advance. Like CHOICE type, ANY
-has no base tag.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Error ::= SEQUENCE {
-  code      INTEGER,
-  parameter ANY DEFINED BY code
-}
-</pre>
-</td></tr></table>
-
-<p>
-The ANY type is frequently used in specifications, where exact type is not
-yet agreed upon between communicating parties or the number of possible
-alternatives of a type is infinite.
-Sometimes an auxiliary selector is kept around to help parties indicate
-the kind of ANY payload in effect ("code" in the example above).
-</p>
-
-<p>
-Values of the ANY type contain serialized ASN.1 value(s) in form of
-an octet string. Therefore pyasn1 Any value object share the properties of
-pyasn1 OctetString object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> someValue = univ.Any(b'\x02\x01\x01')
->>> someValue
-Any(b'\x02\x01\x01')
->>> str(someValue)
-'\x02\x01\x01'
->>> bytes(someValue)
-b'\x02\x01\x01'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Receiving application is supposed to explicitly deserialize the content of Any
-value object, possibly using auxiliary selector for figuring out its ASN.1
-type to pick appropriate decoder.
-</p>
-
-<p>
-There will be some more talk and code snippets covering Any type in the codecs
-chapters that follow.
-</p>
-
-<a name="1.4"></a>
-<h4>
-1.4 Subtype constraints
-</h4>
-
-<p>
-Most ASN.1 types can correspond to an infinite set of values. To adapt to
-particular application's data model and needs, ASN.1 provides a mechanism
-for limiting the infinite set to values, that make sense in particular case.
-</p>
-
-<p>
-Imposing value constraints on an ASN.1 type can also be seen as creating
-a subtype from its base type.
-</p>
-
-<p>
-In pyasn1, constraints take shape of immutable objects capable
-of evaluating given value against constraint-specific requirements.
-Constraint object is a property of pyasn1 type. Like TagSet property,
-associated with every pyasn1 type, constraints can never be modified
-in place. The only way to modify pyasn1 type constraint is to associate
-new constraint object to a new pyasn1 type object.
-</p>
-
-<p>
-A handful of different flavors of <i>constraints</i> are defined in ASN.1.
-We will discuss them one by one in the following chapters and also explain
-how to combine and apply them to types.
-</p>
-
-<a name="1.4.1"></a>
-<h4>
-1.4.1 Single value constraint
-</h4>
-
-<p>
-This kind of constraint allows for limiting type to a finite, specified set
-of values.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-DialButton ::= OCTET STRING (
-  "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-)
-</pre>
-</td></tr></table>
-
-<p>
-Its pyasn1 implementation would look like:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import constraint
->>> c = constraint.SingleValueConstraint(
-  '0','1','2','3','4','5','6','7','8','9'
-)
->>> c
-SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
->>> c('0')
->>> c('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError: 
-  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the snippet above, if a value violates the constraint, an
-exception will be thrown. A constrainted pyasn1 type object holds a
-reference to a constraint object (or their combination, as will be explained
-later) and calls it for value verification.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class DialButton(univ.OctetString):
-...   subtypeSpec = constraint.SingleValueConstraint(
-...       '0','1','2','3','4','5','6','7','8','9'
-...   )
->>> DialButton('0')
-DialButton(b'0')
->>> DialButton('A')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Constrained pyasn1 value object can never hold a violating value.
-</p>
-
-<a name="1.4.2"></a>
-<h4>
-1.4.2 Value range constraint
-</h4>
-
-<p>
-A pair of values, compliant to a type to be constrained, denote low and upper
-bounds of allowed range of values of a type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Teenagers ::= INTEGER (13..19)
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1 terms:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class Teenagers(univ.Integer):
-...   subtypeSpec = constraint.ValueRangeConstraint(13, 19)
->>> Teenagers(14)
-Teenagers(14)
->>> Teenagers(20)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueRangeConstraint(13, 19) failed at: 20
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Value range constraint usually applies numeric types.
-</p>
-
-<a name="1.4.3"></a>
-<h4>
-1.4.3 Size constraint
-</h4>
-
-<p>
-It is sometimes convenient to set or limit the allowed size of a data item
-to be sent from one application to another to manage bandwidth and memory
-consumption issues. Size constraint specifies the lower and upper bounds 
-of the size of a valid value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-TwoBits ::= BIT STRING (SIZE (2))
-</pre>
-</td></tr></table>
-
-<p>
-Express the same grammar in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class TwoBits(univ.BitString):
-...   subtypeSpec = constraint.ValueSizeConstraint(2, 2)
->>> TwoBits((1,1))
-TwoBits("'11'B")
->>> TwoBits((1,1,0))
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Size constraint can be applied to potentially massive values - bit or octet
-strings, SEQUENCE OF/SET OF values.
-</p>
-
-<a name="1.4.4"></a>
-<h4>
-1.4.4 Alphabet constraint
-</h4>
-
-<p>
-The permitted alphabet constraint is similar to Single value constraint
-but constraint applies to individual characters of a value. 
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MorseCode ::= PrintableString (FROM ("."|"-"|" "))
-</pre>
-</td></tr></table>
-
-<p>
-And in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class MorseCode(char.PrintableString):
-...   subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
->>> MorseCode("...---...")
-MorseCode('...---...')
->>> MorseCode("?")
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Current implementation does not handle ranges of characters in constraint
-(FROM "A".."Z" syntax), one has to list the whole set in a range.
-</p>
-
-<a name="1.4.5"></a>
-<h4>
-1.4.5 Constraint combinations
-</h4>
-
-<p>
-Up to this moment, we used a single constraint per ASN.1 type. The standard,
-however, allows for combining multiple individual constraints into
-intersections, unions and exclusions.
-</p>
-
-<p>
-In pyasn1 data model, all of these methods of constraint combinations are
-implemented as constraint-like objects holding individual constraint (or
-combination) objects. Like terminal constraint objects, combination objects
-are capable to perform value verification at its set of enclosed constraints
-according to the logic of particular combination.
-</p>
-
-<p>
-Constraints intersection verification succeeds only if a value is
-compliant to each constraint in a set. To begin with, the following
-specification will constitute a valid telephone number:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
-</pre>
-</td></tr></table>
-
-<p>
-Constraint intersection object serves the logic above:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class PhoneNumber(char.NumericString):
-...   subtypeSpec = constraint.ConstraintsIntersection(
-...     constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-...     constraint.ValueSizeConstraint(11, 11)
-...   )
->>> PhoneNumber('79039343212')
-PhoneNumber('79039343212')
->>> PhoneNumber('?9039343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsIntersection(
-    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-      ValueSizeConstraint(11, 11)) failed at: 
-   PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
->>> PhoneNumber('9343212')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsIntersection(
-    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
-      ValueSizeConstraint(11, 11)) failed at:
-  ValueSizeConstraint(10, 10) failed at: "9343212"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Union of constraints works by making sure that a value is compliant
-to any of the constraint in a set. For instance:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
-</pre>
-</td></tr></table>
-
-<p>
-It's important to note, that a value must fully comply to any single
-constraint in a set. In the specification above, a value of all small or
-all capital letters is compliant, but a mix of small&capitals is not. 
-Here's its pyasn1 analogue:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char, constraint
->>> class CapitalOrSmall(char.IA5String):
-...   subtypeSpec = constraint.ConstraintsUnion(
-...     constraint.PermittedAlphabetConstraint('A','B','C'),
-...     constraint.PermittedAlphabetConstraint('a','b','c')
-...   )
->>> CapitalOrSmall('ABBA')
-CapitalOrSmall('ABBA')
->>> CapitalOrSmall('abba')
-CapitalOrSmall('abba')
->>> CapitalOrSmall('Abba')
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'),
-    PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Finally, the exclusion constraint simply negates the logic of value 
-verification at a constraint. In the following example, any integer value
-is allowed in a type but not zero.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-NoZero ::= INTEGER (ALL EXCEPT 0)
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1 the above definition would read:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> class NoZero(univ.Integer):
-...   subtypeSpec = constraint.ConstraintsExclusion(
-...     constraint.SingleValueConstraint(0)
-...   )
->>> NoZero(1)
-NoZero(1)
->>> NoZero(0)
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The depth of such a constraints tree, built with constraint combination objects
-at its nodes, has not explicit limit. Value verification is performed in a
-recursive manner till a definite solution is found.
-</p>
-
-<a name="1.5"></a>
-<h4>
-1.5 Types relationships
-</h4>
-
-<p>
-In the course of data processing in an application, it is sometimes
-convenient to figure out the type relationships between pyasn1 type or
-value objects. Formally, two things influence pyasn1 types relationship:
-<i>tag set</i> and <i>subtype constraints</i>. One pyasn1 type is considered
-to be a derivative of another if their TagSet and Constraint objects are
-a derivation of one another.
-</p>
-
-<p>
-The following example illustrates the concept (we use the same tagset but
-different constraints for simplicity):
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
->>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
-...    constraint.ValueRangeConstraint(3,8),
-...    constraint.ValueRangeConstraint(4,7)
-... ) )
->>> i1.isSameTypeWith(i2)
-False
->>> i1.isSuperTypeOf(i2)
-True
->>> i1.isSuperTypeOf(i1)
-True
->>> i2.isSuperTypeOf(i1)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As can be seen in the above code snippet, there are two methods of any pyasn1
-type/value object that test types for their relationship:
-<b>isSameTypeWith</b>() and <b>isSuperTypeOf</b>(). The former is 
-self-descriptive while the latter yields true if the argument appears
-to be a pyasn1 object which has tagset and constraints derived from those
-of the object being called.
-</p>
-
-<a name="2"></a>
-<h3>
-2. Codecs
-</h3>
-
-<p>
-In ASN.1 context, 
-<a href=http://en.wikipedia.org/wiki/Codec>codec</a>
-is a program that transforms between concrete data structures and a stream
-of octets, suitable for transmission over the wire. This serialized form of
-data is sometimes called <i>substrate</i> or <i>essence</i>.
-</p>
-
-<p>
-In pyasn1 implementation, substrate takes shape of Python 3 bytes or 
-Python 2 string objects.
-</p>
-
-<p>
-One of the properties of a codec is its ability to cope with incomplete
-data and/or substrate what implies codec to be stateful. In other words, 
-when decoder runs out of substrate and data item being recovered is still 
-incomplete, stateful codec would suspend and complete data item recovery 
-whenever the rest of substrate becomes available. Similarly, stateful encoder
-would encode data items in multiple steps waiting for source data to
-arrive. Codec restartability is especially important when application deals
-with large volumes of data and/or runs on low RAM. For an interesting
-discussion on codecs options and design choices, refer to
-<a href=http://directory.apache.org/subprojects/asn1/>Apache ASN.1 project</a>
-.
-</p>
-
-<p>
-As of this writing, codecs implemented in pyasn1 are all stateless, mostly
-to keep the code simple.
-</p>
-
-<p>
-The pyasn1 package currently supports 
-<a href=http://en.wikipedia.org/wiki/Basic_encoding_rules>BER</a> codec and
-its variations -- 
-<a href=http://en.wikipedia.org/wiki/Canonical_encoding_rules>CER</a> and
-<a href=http://en.wikipedia.org/wiki/Distinguished_encoding_rules>DER</a>.
-More ASN.1 codecs are planned for implementation in the future.
-</p>
-
-<a name="2.1"></a>
-<h4>
-2.1 Encoders
-</h4>
-
-<p>
-Encoder is used for transforming pyasn1 value objects into substrate. Only
-pyasn1 value objects could be serialized, attempts to process pyasn1 type
-objects will cause encoder failure.
-</p>
-
-<p>
-The following code will create a pyasn1 Integer object and serialize it with
-BER encoder:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(univ.Integer(123456))
-b'\x02\x03\x01\xe2@'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-BER standard also defines a so-called <i>indefinite length</i> encoding form
-which makes large data items processing more memory efficient. It is mostly
-useful when encoder does not have the whole value all at once and the
-length of the value can not be determined at the beginning of encoding.
-</p>
-
-<p>
-<i>Constructed encoding</i> is another feature of BER closely related to the
-indefinite length form. In essence, a large scalar value (such as ASN.1
-character BitString type) could be chopped into smaller chunks by encoder
-and transmitted incrementally to limit memory consumption. Unlike indefinite
-length case, the length of the whole value must be known in advance when
-using constructed, definite length encoding form.
-</p>
-
-<p>
-Since pyasn1 codecs are not restartable, pyasn1 encoder may only encode data
-item all at once. However, even in this case, generating indefinite length 
-encoding may help a low-memory receiver, running a restartable decoder,
-to process a large data item.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder
->>> encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   defMode=False,
-...   maxChunkSize=8
-... )
-b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog\x00\x00'
->>>
->>> encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   maxChunkSize=8
-... )
-b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \
-t\x04\x08he lazy \x04\x03dog'
-</pre>
-</td></tr></table>
-
-<p>
-The <b>defMode</b> encoder parameter disables definite length encoding mode,
-while the optional <b>maxChunkSize</b> parameter specifies desired
-substrate chunk size that influences memory requirements at the decoder's end.
-</p>
-
-<p>
-To use CER or DER encoders one needs to explicitly import and call them - the
-APIs are all compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> from pyasn1.codec.cer import encoder as cer_encoder
->>> from pyasn1.codec.der import encoder as der_encoder
->>> ber_encoder.encode(univ.Boolean(True))
-b'\x01\x01\x01'
->>> cer_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>> der_encoder.encode(univ.Boolean(True))
-b'\x01\x01\xff'
->>>
-</pre>
-</td></tr></table>
-
-<a name="2.2"></a>
-<h4>
-2.2 Decoders
-</h4>
-
-<p>
-In the process of decoding, pyasn1 value objects are created and linked to
-each other, based on the information containted in the substrate. Thus,
-the original pyasn1 value object(s) are recovered.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(univ.Boolean(True))
->>> decoder.decode(substrate)
-(Boolean('True(1)'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Commenting on the code snippet above, pyasn1 decoder accepts substrate
-as an argument and returns a tuple of pyasn1 value object (possibly
-a top-level one in case of constructed object) and unprocessed part
-of input substrate.
-</p>
-
-<p>
-All pyasn1 decoders can handle both definite and indefinite length
-encoding modes automatically, explicit switching into one mode
-to another is not required.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(
-...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
-...   defMode=False,
-...   maxChunkSize=8
-... )
->>> decoder.decode(substrate)
-(OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Speaking of BER/CER/DER encoding, in many situations substrate may not contain
-all necessary information needed for complete and accurate ASN.1 values
-recovery. The most obvious cases include implicitly tagged ASN.1 types
-and constrained types.
-</p>
-
-<p>
-As discussed earlier in this handbook, when an ASN.1 type is implicitly
-tagged, previous outermost tag is lost and never appears in substrate.
-If it is the base tag that gets lost, decoder is unable to pick type-specific
-value decoder at its table of built-in types, and therefore recover
-the value part, based only on the information contained in substrate. The
-approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
-a set of them) to <i>guide</i> the decoding process by matching [possibly
-incomplete] tags recovered from substrate with those found in prototype pyasn1
-type objects (also called pyasn1 specification object further in this paper).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import decoder
->>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
-Integer(12), b''
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Decoder would neither modify pyasn1 specification object nor use
-its current values (if it's a pyasn1 value object), but rather use it as
-a hint for choosing proper decoder and as a pattern for creating new objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> i = univ.Integer(12345).subtype(
-...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(i)
->>> substrate
-b'\x9f(\x0209'
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: 
-   TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>> decoder.decode(substrate, asn1Spec=i)
-(Integer(12345), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Notice in the example above, that an attempt to run decoder without passing
-pyasn1 specification object fails because recovered tag does not belong
-to any of the built-in types.
-</p>
-
-<p>
-Another important feature of guided decoder operation is the use of
-values constraints possibly present in pyasn1 specification object.
-To explain this, we will decode a random integer object into generic Integer
-and the constrained one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, constraint
->>> from pyasn1.codec.ber import encoder, decoder
->>> class DialDigit(univ.Integer):
-...   subtypeSpec = constraint.ValueRangeConstraint(0,9)
->>> substrate = encoder.encode(univ.Integer(13))
->>> decoder.decode(substrate)
-(Integer(13), b'')
->>> decoder.decode(substrate, asn1Spec=DialDigit())
-Traceback (most recent call last):
-...
-pyasn1.type.error.ValueConstraintError:
-  ValueRangeConstraint(0, 9) failed at: 13
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Similarily to encoders, to use CER or DER decoders application has to
-explicitly import and call them - all APIs are compatible.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder as ber_encoder
->>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
->>>
->>> from pyasn1.codec.ber import decoder as ber_decoder
->>> from pyasn1.codec.cer import decoder as cer_decoder
->>> from pyasn1.codec.der import decoder as der_decoder
->>> 
->>> ber_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> cer_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> der_decoder.decode(substrate)
-(OctetString(b'http://pyasn1.sf.net'), b'')
->>> 
-</pre>
-</td></tr></table>
-
-<a name="2.2.1"></a>
-<h4>
-2.2.1 Decoding untagged types
-</h4>
-
-<p>
-It has already been mentioned, that ASN.1 has two "special case" types:
-CHOICE and ANY. They are different from other types in part of 
-tagging - unless these two are additionally tagged, neither of them will
-have their own tag. Therefore these types become invisible in substrate
-and can not be recovered without passing pyasn1 specification object to
-decoder.
-</p>
-
-<p>
-To explain the issue, we will first prepare a Choice object to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedtype
->>> class CodeOrMessage(univ.Choice):
-...   componentType = namedtype.NamedTypes(
-...     namedtype.NamedType('code', univ.Integer()),
-...     namedtype.NamedType('message', univ.OctetString())
-...   )
->>>
->>> codeOrMessage = CodeOrMessage()
->>> codeOrMessage.setComponentByName('message', 'my string value')
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Let's now encode this Choice object and then decode its substrate
-with and without pyasn1 specification object:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.codec.ber import encoder, decoder
->>> substrate = encoder.encode(codeOrMessage)
->>> substrate
-b'\x04\x0fmy string value'
->>> encoder.encode(univ.OctetString('my string value'))
-b'\x04\x0fmy string value'
->>>
->>> decoder.decode(substrate)
-(OctetString(b'my string value'), b'')
->>> codeOrMessage, substrate = decoder.decode(substrate, asn1Spec=CodeOrMessage())
->>> print(codeOrMessage.prettyPrint())
-CodeOrMessage:
- message=b'my string value'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-First thing to notice in the listing above is that the substrate produced
-for our Choice value object is equivalent to the substrate for an OctetString
-object initialized to the same value. In other words, any information about
-the Choice component is absent in encoding.
-</p>
-
-<p>
-Sure enough, that kind of substrate will decode into an OctetString object,
-unless original Choice type object is passed to decoder to guide the decoding
-process.
-</p>
-
-<p>
-Similarily untagged ANY type behaves differently on decoding phase - when
-decoder bumps into an Any object in pyasn1 specification, it stops decoding
-and puts all the substrate into a new Any value object in form of an octet
-string. Concerned application could then re-run decoder with an additional,
-more exact pyasn1 specification object to recover the contents of Any
-object.
-</p>
-
-<p>
-As it was mentioned elsewhere in this paper, Any type allows for incomplete
-or changing ASN.1 specification to be handled gracefully by decoder and
-applications.
-</p>
-
-<p>
-To illustrate the working of Any type, we'll have to make the stage
-by encoding a pyasn1 object and then putting its substrate into an any
-object.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
->>> innerSubstrate = encoder.encode(univ.Integer(1234))
->>> innerSubstrate
-b'\x02\x02\x04\xd2'
->>> any = univ.Any(innerSubstrate)
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> substrate = encoder.encode(any)
->>> substrate
-b'\x02\x02\x04\xd2'
->>>
-</pre>
-</td></tr></table>
-
-<p>
-As with Choice type encoding, there is no traces of Any type in substrate.
-Obviously, the substrate we are dealing with, will decode into the inner
-[Integer] component, unless pyasn1 specification is given to guide the 
-decoder. Continuing previous code:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> from pyasn1.codec.ber import encoder, decoder
-
->>> decoder.decode(substrate)
-(Integer(1234), b'')
->>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
->>> any
-Any(b'\x02\x02\x04\xd2')
->>> decoder.decode(str(any))
-(Integer(1234), b'')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Both CHOICE and ANY types are widely used in practice. Reader is welcome to
-take a look at 
-<a href=http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>
-ASN.1 specifications of X.509 applications</a> for more information.
-</p>
-
-<a name="2.2.2"></a>
-<h4>
-2.2.2 Ignoring unknown types
-</h4>
-
-<p>
-When dealing with a loosely specified ASN.1 structure, the receiving
-end may not be aware of some types present in the substrate. It may be
-convenient then to turn decoder into a recovery mode. Whilst there, decoder
-will not bail out when hit an unknown tag but rather treat it as an Any
-type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> from pyasn1.codec.ber import encoder, decoder
->>> taggedInt = univ.Integer(12345).subtype(
-...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> substrate = encoder.encode(taggedInt)
->>> decoder.decode(substrate)
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
->>>
->>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
->>> decoder.decode(substrate)
-(Any(b'\x9f(\x0209'), '')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-It's also possible to configure a custom decoder, to handle unknown tags
-found in substrate. This can be done by means of <b>defaultRawDecoder</b>
-attribute holding a reference to type decoder object. Refer to the source
-for API details.
-</p>
-
-<a name="3"></a>
-<h3>
-3. Feedback and getting help
-</h3>
-
-<p>
-Although pyasn1 software is almost a decade old and used in many production
-environments, it still may have bugs and non-implemented pieces. Anyone
-who happens to run into such defect is welcome to complain to
-<a href=mailto:pyasn1-users@lists.sourceforge.net>pyasn1 mailing list</a>
-or better yet fix the issue and send
-<a href=mailto:ilya@glas.net>me</a> the patch.
-</p>
-
-<p>
-Typically, pyasn1 is used for building arbitrary protocol support into
-various applications. This involves manual translation of ASN.1 data
-structures into their pyasn1 implementations. To save time and effort,
-data structures for some of the popular protocols are pre-programmed
-and kept for further re-use in form of the
-<a href=http://sourceforge.net/projects/pyasn1/files/pyasn1-modules/>
-pyasn1-modules package</a>. For instance, many structures for PKI (X.509,
-PKCS#*, CRMF, OCSP), LDAP and SNMP are present.
-Applications authors are advised to import and use relevant modules 
-from that package whenever needed protocol structures are already 
-there. New protocol modules contributions are welcome.
-</p>
-
-<p>
-And finally, the latest pyasn1 package revision is available for free
-download from
-<a href=http://sourceforge.net/projects/pyasn1/>project home</a> and
-also from the 
-<a href=http://pypi.python.org/pypi>Python package repository</a>.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/scalar.html
+++ /dev/null
@@ -1,794 +0,0 @@
-<html>
-<title>
-PyASN1 data model and scalar types
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-
-<h3>
-1. Data model for ASN.1 types
-</h3>
-
-<p>
-All ASN.1 types could be categorized into two groups: scalar (also called
-simple or primitive) and constructed. The first group is populated by
-well-known types like Integer or String. Members of constructed group
-hold other types (simple or constructed) as their inner components, thus
-they are semantically close to a programming language records or lists.
-</p>
-
-<p>
-In pyasn1, all ASN.1 types and values are implemented as Python objects.
-The same pyasn1 object can represent either ASN.1 type and/or value
-depending of the presense of value initializer on object instantiation.
-We will further refer to these as <i>pyasn1 type object</i> versus <i>pyasn1
-value object</i>.
-</p>
-
-<p>
-Primitive ASN.1 types are implemented as immutable scalar objects. There values
-could be used just like corresponding native Python values (integers,
-strings/bytes etc) and freely mixed with them in expressions.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerValue = univ.Integer(12)
->>> asn1IntegerValue - 2
-10
->>> univ.OctetString('abc') == 'abc'
-True   # Python 2
->>> univ.OctetString(b'abc') == b'abc'
-True   # Python 3
-</pre>
-</td></tr></table>
-
-<p>
-It would be an error to perform an operation on a pyasn1 type object
-as it holds no value to deal with:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> asn1IntegerType = univ.Integer()
->>> asn1IntegerType - 2
-...
-pyasn1.error.PyAsn1Error: No value for __coerce__()
-</pre>
-</td></tr></table>
-
-<a name="1.1"></a>
-<h4>
-1.1 Scalar types
-</h4>
-
-<p>
-In the sub-sections that follow we will explain pyasn1 mapping to those
-primitive ASN.1 types. Both, ASN.1 notation and corresponding pyasn1
-syntax will be given in each case.
-</p>
-
-<a name="1.1.1"></a>
-<h4>
-1.1.1 Boolean type
-</h4>
-
-<p>
-This is the simplest type those values could be either True or False.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-FunFactorPresent ::= BOOLEAN
-
-;; values declaration and assignment
-pythonFunFactor FunFactorPresent ::= TRUE
-cobolFunFactor FunFactorPresent :: FALSE
-</pre>
-</td></tr></table>
-
-<p>
-And here's pyasn1 version of it:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> class FunFactorPresent(univ.Boolean): pass
-... 
->>> pythonFunFactor = FunFactorPresent(True)
->>> cobolFunFactor = FunFactorPresent(False)
->>> pythonFunFactor
-FunFactorPresent('True(1)')
->>> cobolFunFactor
-FunFactorPresent('False(0)')
->>> pythonFunFactor == cobolFunFactor
-False
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.2"></a>
-<h4>
-1.1.2 Null type
-</h4>
-
-<p>
-The NULL type is sometimes used to express the absense of any information.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; type specification
-Vote ::= CHOICE {
-  agreed BOOLEAN,
-  skip NULL
-}
-</td></tr></table>
-
-;; value declaration and assignment
-myVote Vote ::= skip:NULL
-</pre>
-
-<p>
-We will explain the CHOICE type later in this paper, meanwhile the NULL
-type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> skip = univ.Null()
->>> skip
-Null('')
->>>
-</pre>
-</td></tr></table>
-
-<a name="1.1.3"></a>
-<h4>
-1.1.3 Integer type
-</h4>
-
-<p>
-ASN.1 defines the values of Integer type as negative or positive of whatever
-length. This definition plays nicely with Python as the latter places no
-limit on Integers. However, some ASN.1 implementations may impose certain
-limits of integer value ranges. Keep that in mind when designing new
-data structures.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; values specification
-age-of-universe INTEGER ::= 13750000000
-mean-martian-surface-temperature INTEGER ::= -63
-</pre>
-</td></tr></table>
-
-<p>
-A rather strigntforward mapping into pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> ageOfUniverse = univ.Integer(13750000000)
->>> ageOfUniverse
-Integer(13750000000)
->>>
->>> meanMartianSurfaceTemperature = univ.Integer(-63)
->>> meanMartianSurfaceTemperature
-Integer(-63)
->>>
-</pre>
-</td></tr></table>
-
-<p>
-ASN.1 allows to assign human-friendly names to particular values of
-an INTEGER type.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-Temperature ::= INTEGER {
-  freezing(0),
-  boiling(100) 
-}
-</pre>
-</td></tr></table>
-
-<p>
-The Temperature type expressed in pyasn1:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class Temperature(univ.Integer):
-...   namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
-...
->>> t = Temperature(0)
->>> t
-Temperature('freezing(0)')
->>> t + 1
-Temperature(1)
->>> t + 100
-Temperature('boiling(100)')
->>> t = Temperature('boiling')
->>> t
-Temperature('boiling(100)')
->>> Temperature('boiling') / 2
-Temperature(50)
->>> -1 < Temperature('freezing')
-True
->>> 47 > Temperature('boiling')
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-These values labels have no effect on Integer type operations, any value
-still could be assigned to a type (information on value constraints will
-follow further in this paper).
-</p>
-
-<a name="1.1.4"></a>
-<h4>
-1.1.4 Enumerated type
-</h4>
-
-<p>
-ASN.1 Enumerated type differs from an Integer type in a number of ways.
-Most important is that its instance can only hold a value that belongs
-to a set of values specified on type declaration.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-error-status ::= ENUMERATED {
-  no-error(0),
-  authentication-error(10),
-  authorization-error(20),
-  general-failure(51)
-}
-</pre>
-</td></tr></table>
-
-<p>
-When constructing Enumerated type we will use two pyasn1 features: values
-labels (as mentioned above) and value constraint (will be described in
-more details later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval, constraint
->>> class ErrorStatus(univ.Enumerated):
-...   namedValues = namedval.NamedValues(
-...        ('no-error', 0),
-...        ('authentication-error', 10),
-...        ('authorization-error', 20),
-...        ('general-failure', 51)
-...   )
-...   subtypeSpec = univ.Enumerated.subtypeSpec + \
-...                    constraint.SingleValueConstraint(0, 10, 20, 51)
-...
->>> errorStatus = univ.ErrorStatus('no-error')
->>> errorStatus
-ErrorStatus('no-error(0)')
->>> errorStatus == univ.ErrorStatus('general-failure')
-False
->>> univ.ErrorStatus('non-existing-state')
-Traceback (most recent call last):
-...
-pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Particular integer values associated with Enumerated value states
-have no meaning. They should not be used as such or in any kind of
-math operation. Those integer values are only used by codecs to
-transfer state from one entity to another.
-</p>
-
-<a name="1.1.5"></a>
-<h4>
-1.1.5 Real type
-</h4>
-
-<p>
-Values of the Real type are a three-component tuple of mantissa, base and 
-exponent. All three are integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-pi ::= REAL { mantissa 314159, base 10, exponent -5 }
-</pre>
-</td></tr></table>
-
-<p>
-Corresponding pyasn1 objects can be initialized with either a three-component
-tuple or a Python float. Infinite values could be expressed in a way, 
-compatible with Python float type.
-
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> pi = univ.Real((314159, 10, -5))
->>> pi
-Real((314159, 10,-5))
->>> float(pi)
-3.14159
->>> pi == univ.Real(3.14159)
-True
->>> univ.Real('inf')
-Real('inf')
->>> univ.Real('-inf') == float('-inf')
-True
->>>
-</pre>
-</td></tr></table>
-
-<p>
-If a Real object is initialized from a Python float or yielded by a math
-operation, the base is set to decimal 10 (what affects encoding).
-</p>
-
-<a name="1.1.6"></a>
-<h4>
-1.1.6 Bit string type
-</h4>
-
-<p>
-ASN.1 BIT STRING type holds opaque binary data of an arbitrarily length.
-A BIT STRING value could be initialized by either a binary (base 2) or 
-hex (base 16) value.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-public-key BIT STRING ::= '1010111011110001010110101101101
-                           1011000101010000010110101100010
-                           0110101010000111101010111111110'B
-
-signature  BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
-</pre>
-</td></tr></table>
-
-<p>
-The pyasn1 BitString objects can initialize from native ASN.1 notation
-(base 2 or base 16 strings) or from a Python tuple of binary components.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> publicKey = univ.BitString(
-...          "'1010111011110001010110101101101"
-...          "1011000101010000010110101100010"
-...          "0110101010000111101010111111110'B"
-)
->>> publicKey
-BitString("'10101110111100010101101011011011011000101010000010110101100010\
-0110101010000111101010111111110'B")
->>> signature = univ.BitString(
-...          "'AF01330CD932093392100B39FF00DE0'H"
-... )
->>> signature
-BitString("'101011110000000100110011000011001101100100110010000010010011001\
-1100100100001000000001011001110011111111100000000110111100000'B")
->>> fingerprint = univ.BitString(
-...          (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
-... )
->>> fingerprint
-BitString("'101101110101'B")
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Another BIT STRING initialization method supported by ASN.1 notation
-is to specify only 1-th bits along with their human-friendly label
-and bit offset relative to the beginning of the bit string. With this 
-method, all not explicitly mentioned bits are doomed to be zeros.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-bit-mask  BIT STRING ::= {
-  read-flag(0),
-  write-flag(2),
-  run-flag(4)
-}
-</pre>
-</td></tr></table>
-
-<p>
-To express this in pyasn1, we will employ the named values feature (as with
-Enumeration type).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, namedval
->>> class BitMask(univ.BitString):
-...   namedValues = namedval.NamedValues(
-...        ('read-flag', 0),
-...        ('write-flag', 2),
-...        ('run-flag', 4)
-... )
->>> bitMask = BitMask('read-flag,run-flag')
->>> bitMask
-BitMask("'10001'B")
->>> tuple(bitMask)
-(1, 0, 0, 0, 1)
->>> bitMask[4]
-1
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The BitString objects mimic the properties of Python tuple type in part
-of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.7"></a>
-<h4>
-1.1.7 OctetString type
-</h4>
-
-<p>
-The OCTET STRING type is a confusing subject. According to ASN.1
-specification, this type is similar to BIT STRING, the major difference
-is that the former operates in 8-bit chunks of data. What is important
-to note, is that OCTET STRING was NOT designed to handle text strings - the
-standard provides many other types specialized for text content. For that
-reason, ASN.1 forbids to initialize OCTET STRING values with "quoted text
-strings", only binary or hex initializers, similar to BIT STRING ones,
-are allowed.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
-thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
-</pre>
-</td></tr></table>
-
-<p>
-However, ASN.1 users (e.g. protocols designers) seem to ignore the original
-purpose of the OCTET STRING type - they used it for handling all kinds of
-data, including text strings.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, we have taken a liberal approach and allowed both BIT STRING
-style and quoted text initializers for the OctetString objects. To avoid
-possible collisions, quoted text is the default initialization syntax.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> thumbnail = univ.OctetString(
-...    binValue='1000010111101110101111000000111011'
-... )
->>> thumbnail
-OctetString(hexValue='85eebcec0')
->>> thumbnail = univ.OctetString(
-...    hexValue='FA9823C43E43510DE3422'
-... )
->>> thumbnail
-OctetString(hexValue='fa9823c43e4351de34220')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Most frequent usage of the OctetString class is to instantiate it with
-a text string.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
->>> welcomeMessage
-OctetString(b'Welcome to ASN.1 wilderness!')
->>> print('%s' % welcomeMessage)
-Welcome to ASN.1 wilderness!
->>> welcomeMessage[11:16]
-OctetString(b'ASN.1')
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-OctetString objects support the immutable sequence object protocol.
-In other words, they behave like Python 3 bytes (or Python 2 strings).
-</p>
-
-<p>
-When running pyasn1 on Python 3, it's better to use the bytes objects for
-OctetString instantiation, as it's more reliable and efficient.
-</p>
-
-<p>
-Additionally, OctetString's can also be instantiated with a sequence of
-8-bit integers (ASCII codes).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> univ.OctetString((77, 101, 101, 103, 111))
-OctetString(b'Meego')
-</pre>
-</td></tr></table>
-
-<p>
-It is sometimes convenient to express OctetString instances as 8-bit
-characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> octetString = univ.OctetString('ABCDEF')
->>> octetString.asNumbers()
-(65, 66, 67, 68, 69, 70)
->>> octetString.asOctets()
-b'ABCDEF'
-</pre>
-</td></tr></table>
-
-<a name="1.1.8"></a>
-<h4>
-1.1.8 ObjectIdentifier type
-</h4>
-
-<p>
-Values of the OBJECT IDENTIFIER type are sequences of integers that could
-be used to identify virtually anything in the world. Various ASN.1-based
-protocols employ OBJECT IDENTIFIERs for their own identification needs.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-internet-id OBJECT IDENTIFIER ::= {
-  iso(1) identified-organization(3) dod(6) internet(1)
-}
-</pre>
-</td></tr></table>
-
-<p>
-One of the natural ways to map OBJECT IDENTIFIER type into a Python
-one is to use Python tuples of integers. So this approach is taken by
-pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
->>> internetId
-ObjectIdentifier('1.3.6.1')
->>> internetId[2]
-6
->>> internetId[1:3]
-ObjectIdentifier('3.6')
-</pre>
-</td></tr></table>
-
-<p>
-A more human-friendly "dotted" notation is also supported.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ
->>> univ.ObjectIdentifier('1.3.6.1')
-ObjectIdentifier('1.3.6.1')
-</pre>
-</td></tr></table>
-
-<p>
-Symbolic names of the arcs of object identifier, sometimes present in
-ASN.1 specifications, are not preserved and used in pyasn1 objects.
-</p>
-
-<p>
-The ObjectIdentifier objects mimic the properties of Python tuple type in
-part of immutable sequence object protocol support.
-</p>
-
-<a name="1.1.9"></a>
-<h4>
-1.1.9 Character string types
-</h4>
-
-<p>
-ASN.1 standard introduces a diverse set of text-specific types. All of them
-were designed to handle various types of characters. Some of these types seem
-be obsolete nowdays, as their target technologies are gone. Another issue
-to be aware of is that raw OCTET STRING type is sometimes used in practice
-by ASN.1 users instead of specialized character string types, despite
-explicit prohibition imposed by ASN.1 specification.
-</p>
-
-<p>
-The two types are specific to ASN.1 are NumericString and PrintableString.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-welcome-message ::= PrintableString {
-  "Welcome to ASN.1 text types"
-}
-
-dial-pad-numbers ::= NumericString {
-  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
-}
-</pre>
-</td></tr></table>
-
-<p>
-Their pyasn1 implementations are:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
-'Welcome to ASN.1 text types'
->>> dialPadNumbers = char.NumericString(
-      "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
-)
->>> dialPadNumbers
-NumericString(b'0123456789')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The following types came to ASN.1 from ISO standards on character sets.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.VisibleString("abc")
-VisibleString(b'abc')
->>> char.IA5String('abc')
-IA5String(b'abc')
->>> char.TeletexString('abc')
-TeletexString(b'abc')
->>> char.VideotexString('abc')
-VideotexString(b'abc')
->>> char.GraphicString('abc')
-GraphicString(b'abc')
->>> char.GeneralString('abc')
-GeneralString(b'abc')
->>>
-</pre>
-</td></tr></table>
-
-<p>
-The last three types are relatively recent addition to the family of
-character string types: UniversalString, BMPString, UTF8String.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import char
->>> char.UniversalString("abc")
-UniversalString(b'abc')
->>> char.BMPString('abc')
-BMPString(b'abc')
->>> char.UTF8String('abc')
-UTF8String(b'abc')
->>> utf8String = char.UTF8String('У попа была собака')
->>> utf8String
-UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0 \
-\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
->>> print(utf8String)
-У попа была собака
->>>
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, all character type objects behave like Python strings. None of
-them is currently constrained in terms of valid alphabet so it's up to
-the data source to keep an eye on data validation for these types.
-</p>
-
-<a name="1.1.10"></a>
-<h4>
-1.1.10 Useful types
-</h4>
-
-<p>
-There are three so-called useful types defined in the standard:
-ObjectDescriptor, GeneralizedTime, UTCTime. They all are subtypes
-of GraphicString or VisibleString types therefore useful types are
-character string types.
-</p>
-
-<p>
-It's advised by the ASN.1 standard to have an instance of ObjectDescriptor
-type holding a human-readable description of corresponding instance of
-OBJECT IDENTIFIER type. There are no formal linkage between these instances
-and provision for ObjectDescriptor uniqueness in the standard.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> descrBER = useful.ObjectDescriptor(
-      "Basic encoding of a single ASN.1 type"
-)
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-GeneralizedTime and UTCTime types are designed to hold a human-readable
-timestamp in a universal and unambiguous form. The former provides
-more flexibility in notation while the latter is more strict but has
-Y2K issues.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-;; Mar 8 2010 12:00:00 MSK
-moscow-time GeneralizedTime ::= "20110308120000.0"
-;; Mar 8 2010 12:00:00 UTC
-utc-time GeneralizedTime ::= "201103081200Z"
-;; Mar 8 1999 12:00:00 UTC
-utc-time UTCTime ::= "9803081200Z"
-</pre>
-</td></tr></table>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import useful
->>> moscowTime = useful.GeneralizedTime("20110308120000.0")
->>> utcTime = useful.UTCTime("9803081200Z")
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-Despite their intended use, these types possess no special, time-related,
-handling in pyasn1. They are just printable strings.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/changelog.rst
@@ -0,0 +1,6 @@
+
+Changelog
+=========
+
+.. include:: ../../CHANGES.rst
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/conf.py
@@ -0,0 +1,323 @@
+# -*- coding: utf-8 -*-
+#
+# PyASN1 documentation build configuration file, created by
+# sphinx-quickstart on Sat Jun 27 23:15:54 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+import shlex
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.doctest',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.todo'
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The encoding of source files.
+# source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'contents'
+
+# General information about the project.
+project = u'PyASN1'
+# noinspection PyShadowingBuiltins
+copyright = u'2005-2017, Ilya Etingof <etingof@gmail.com>'
+author = u'Ilya Etingof <etingof@gmail.com>'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.3'
+# The full version, including alpha/beta/rc tags.
+release = '0.3.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+# today = ''
+# Else, today_fmt is used as the format for a strftime call.
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+# html_theme = 'alabaster'
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+# html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+html_title = "PyASN1"
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+# html_logo = ""
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+# html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+if 'PYASN1DEV' in os.environ:
+    html_static_path = ['.static']
+
+# Custom CSS theme
+if 'PYASN1DEV' in os.environ:
+    html_style = 'css/rtdimproved.css'
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+# html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+# html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+# html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+# html_additional_pages = {}
+
+# If false, no module index is generated.
+# html_domain_indices = True
+
+# If false, no index is generated.
+# html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
+# html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+# html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+# html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'pyasn1doc'
+
+html_context = {
+    'include_analytics': 'PYASN1DEV' in os.environ
+}
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, 'PyASN1.tex', u'PyASN1 Documentation',
+     u'Ilya Etingof \\textless{}etingof@gmail.com\\textgreater{}', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+# latex_appendices = []
+
+# If false, no module index is generated.
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    (master_doc, 'pyasn1', u'PyASN1 Documentation',
+     [author], 1)
+]
+
+# If true, show URL addresses after external links.
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (master_doc, 'PyASN1', u'PyASN1 Documentation',
+     author, 'PyASN1', 'One line description of project.',
+     'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+# texinfo_no_detailmenu = False
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'python': ('https://docs.python.org/3.4/', None)}
+
+# this merges constructor docstring with class docstring
+autoclass_content = 'both'
+# Sort members by type
+autodoc_member_order = 'bysource'
+# autodoc_member_order = 'groupwise'
+
+# Napoleon settings
+napoleon_google_docstring = False
+napoleon_numpy_docstring = True
+napoleon_include_private_with_doc = False
+napoleon_include_special_with_doc = True
+napoleon_use_admonition_for_examples = False
+napoleon_use_admonition_for_notes = False
+napoleon_use_admonition_for_references = False
+napoleon_use_ivar = False
+napoleon_use_param = False
+napoleon_use_rtype = False
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/contents.rst
@@ -0,0 +1,194 @@
+
+ASN.1 library for Python
+========================
+
+.. toctree::
+   :maxdepth: 2
+
+Abstract Syntax Notation One (`ASN.1
+<http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_1x>`_) is a
+technology for exchanging structured data in a universally understood,
+hardware agnostic way. Many industrial, security and telephony
+applications heavily rely on ASN.1.
+
+The `pyasn1 <https://pypi.python.org/pypi/pyasn1/>`_ library implements
+ASN.1 support in pure-Python.
+
+What is ASN.1
+-------------
+
+ASN.1 is a large, arguably over-engineered and extremely old data modelling and
+serialization tool. It is probably among the first serialization protocols in
+the history of computer science and technology.
+
+ASN.1 started its life over 30 years ago as a serialization mechanism for the first
+electronic mail (known as X.400). Later on if was split off the e-mail application
+and become a stand-alone tech still being actively supported by its designers
+and widely used in industry and technology.
+
+Since then ASN.1 is sort of haunted by its relations with the OSI model -- the
+first, unsuccessful, version of the Internet. You can read many interesting
+`discussions <https://news.ycombinator.com/item?id=8871453>`_ on that topic.
+
+In the following years, generations of software engineers tackled the serialization
+problem many times. We can see that in Google's `ProtoBuffers <https://developers.google.com/protocol-buffers/>`_
+or `FlatBuffers <https://google.github.io/flatbuffers/>`_, for example.
+Interestingly, many new takes on binary protocol design do not depart
+far from ASN.1 from technical perspective. It's more of a matter of striking
+a balance between processing overhead, wire format overhead and human
+readability.
+
+Looking at what ASN.1 has to offer, it has three loosely coupled parts:
+
+* Data types: the standard introduces a collection of basic data types
+  (integers, bits, strings, arrays and records) that can be used for describing
+  arbitrarily complex, nested data structures.
+
+* Serialization protocols: the above data structures could be converted into a
+  series of octets for storage or transmission over the wire as well as
+  recovered back into their structured form. The system is fully agnostic
+  to hardware architectures differences.
+
+* Schema language: ASN.1 data structures could be described in terms
+  of a schema language for ASN.1 compiler to turn it into platform-specific
+  implementation.
+
+ASN.1 applications
+------------------
+
+Being an old and generally successful standard, ASN.1 is widely
+adopted for many uses. To give you an example, these technologies
+use ASN.1 for their data exchange needs:
+
+* Signaling standards for the public switched telephone network (SS7 family)
+* Network management standards (SNMP, CMIP)
+* Directory standards (X.500 family, LDAP)
+* Public Key Infrastructure standards (X.509, etc.)
+* PBX control (CSTA)
+* IP-based Videoconferencing (H.323 family)
+* Biometrics (BIP, CBEFF, ACBio)
+* Intelligent transportation (SAE J2735)
+* Cellular telephony (GSM, GPRS/EDGE, UMTS, LTE)
+
+ASN.1 gotchas
+-------------
+
+Apparently, ASN.1 is hard to implement properly. Quality open-source
+ASN.1 tools are rare, but ad-hoc implementations are numerous. Judging from the
+`statistics <http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ASN.1>`_ on discovered
+security vulnerabilities, many people have implemented ASN.1 parsers
+and oftentimes fell victim to its edge cases.
+
+On the bright side, ASN.1 has been around for a long time, it is well understood
+and security reviewed.
+
+Library capabilities
+--------------------
+
+As of this moment, pyasn1 library implements all ASN.1 data
+types as Python objects in accordance with X.208 standard. Later,
+post-1995, revision (X.680) introduced some changes to the schema
+language which may not be fully supported by pyasn1. Aside from data
+types a collection of data transformation codecs comes with pyasn1 package.
+
+As for ASN.1 schema language, pyasn1 package does
+not ship any compiler for it. However, there's a tool called
+`asn1late <https://github.com/kimgr/asn1ate>`_ which is an ASN.1
+grammar parser paired to code generator capable of generating pyasn1
+code. So this is an alternative (or at least a good start) to manual
+implementation of pyasn1 classes from ASN.1 specification.
+
+Both `pyasn1 <https://github.com/etingof/pyasn1>`_ and
+`pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_ libraries
+can be used out-of-the-box with Python versions 2.4 through 3.6.
+No external dependencies required.
+
+Documentation
+-------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/tutorial
+   /docs/api-reference
+
+Use case
+--------
+
+   .. toctree::
+      :maxdepth: 2
+
+      /example-use-case
+
+Download & Install
+------------------
+
+The PyASN1 software is provided under terms and conditions of BSD-style
+:ref:`license`, and can be freely downloaded from `Github <https://github.com/etingof/pyasn1>`_
+or `PyPI <http://pypi.python.org/pypi/pyasn1/>`_.
+
+It is pure-Python and has no dependencies. Considering how much industrial or finance
+software can be stuck with an old platform (think RHEL 5), we struggle to maintain its
+compatibility back to the very pre-historic Python (which is 2.4!).
+
+The best way to obtain PyASN1 is by running `pip`:
+
+.. code-block:: bash
+
+   $ pip install pyasn1
+
+or
+
+.. code-block:: bash
+
+   $ easy_install pyasn1
+
+You may also want to use `pyasn1-modules`:
+
+.. code-block:: bash
+
+   $ pip install pyasn1-modules
+
+Changes
+-------
+
+All changes and release history is maintained in changelog.  There you
+could also download the latest unreleased pyasn1 tarball containing
+the latest fixes and improvements.
+
+   .. toctree::
+      :maxdepth: 1
+
+      /changelog
+
+Getting help
+------------
+
+Please, file your `issues <https://github.com/etingof/pyasn1/issues>`_
+and `PRs <https://github.com/etingof/pyasn1/pulls>`_ at GitHub.
+Alternatively, you could ask for help at
+`Stack Overflow <http://stackoverflow.com/questions/tagged/pyasn1>`_
+or search
+`pyasn1-users <https://lists.sourceforge.net/lists/listinfo/pyasn1-users>`_
+mailing list archive.
+
+Books on ASN.1
+--------------
+
+The pyasn1 implementation is largely based on reading up the following awesome
+books:
+
+* `ASN.1 - Communication between heterogeneous systems <http://www.oss.com/asn1/dubuisson.html>`_ by Olivier Dubuisson
+* `ASN.1 Complete <http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf>`_ by Prof John Larmouth
+
+Here you can get the official standards which is hard to read:
+
+* `ITU standards <http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-X.693-0207w.zip>`_
+
+On the other end of the readability spectrum, here is a quick and sweet write up:
+
+* `A Layman's Guide to a Subset of ASN.1, BER, and DER <ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc>`_ by Burton S. Kaliski
+
+If you are working with ASN.1, we'd highly recommend reading a proper
+book on the subject.
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/api-reference.rst
@@ -0,0 +1,30 @@
+
+Library reference
+=================
+
+.. toctree::
+   :maxdepth: 2
+
+ASN.1 types
+-----------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/univ/contents
+   /docs/type/char/contents
+   /docs/type/useful/contents
+   /docs/type/tag/contents
+   /docs/type/namedtype/contents
+   /docs/type/namedval/contents
+
+Transformation codecs
+---------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/codec/ber/contents
+   /docs/codec/cer/contents
+   /docs/codec/der/contents
+   /docs/codec/native/contents
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/ber/contents.rst
@@ -0,0 +1,7 @@
+
+Basic Encoding Rules
+--------------------
+
+.. autofunction:: pyasn1.codec.ber.encoder.encode(value, defMode=True, maxChunkSize=0)
+
+.. autofunction:: pyasn1.codec.ber.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/cer/contents.rst
@@ -0,0 +1,7 @@
+
+Canonical Encoding Rules
+------------------------
+
+.. autofunction:: pyasn1.codec.cer.encoder.encode(value)
+
+.. autofunction:: pyasn1.codec.cer.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/der/contents.rst
@@ -0,0 +1,7 @@
+
+Distinguished Encoding Rules
+----------------------------
+
+.. autofunction:: pyasn1.codec.der.encoder.encode(value)
+
+.. autofunction:: pyasn1.codec.der.decoder.decode(substrate, asn1Spec=None)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/codec/native/contents.rst
@@ -0,0 +1,7 @@
+
+Native Python types
+-------------------
+
+.. autofunction:: pyasn1.codec.native.encoder.encode(asn1Value)
+
+.. autofunction:: pyasn1.codec.native.decoder.decode(pyObject, asn1Spec)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/tutorial.rst
@@ -0,0 +1,1778 @@
+
+Documentation
+=============
+
+.. toctree::
+   :maxdepth: 2
+
+Data model for ASN.1 types
+--------------------------
+
+All ASN.1 types could be categorized into two groups: scalar (also
+called simple or primitive) and constructed. The first group is
+populated by well-known types like Integer or String. Members of
+constructed group hold other types (simple or constructed) as their
+inner components, thus they are semantically close to a programming
+language records or lists.
+
+In pyasn1, all ASN.1 types and values are implemented as Python
+objects.  The same pyasn1 object can represent either ASN.1 type
+and/or value depending of the presense of value initializer on object
+instantiation.  We will further refer to these as *pyasn1 type object*
+versus *pyasn1 value object*.
+
+Primitive ASN.1 types are implemented as immutable scalar objects.
+There values could be used just like corresponding native Python
+values (integers, strings/bytes etc) and freely mixed with them in
+expressions.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> asn1IntegerValue = univ.Integer(12)
+   >>> asn1IntegerValue - 2
+   10
+   >>> univ.OctetString('abc') == 'abc'
+   True   # Python 2
+   >>> univ.OctetString(b'abc') == b'abc'
+   True   # Python 3
+
+It would be an error to perform an operation on a pyasn1 type object
+as it holds no value to deal with:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> asn1IntegerType = univ.Integer()
+   >>> asn1IntegerType - 2
+   ...
+   pyasn1.error.PyAsn1Error: No value for __coerce__()
+
+
+Scalar types
+------------
+
+In the sub-sections that follow we will explain pyasn1 mapping to
+those primitive ASN.1 types. Both, ASN.1 notation and corresponding
+pyasn1 syntax will be given in each case.
+
+Boolean type
+++++++++++++
+
+*BOOLEAN* is the simplest type those values could be either True or
+False.
+
+.. code-block:: bash
+
+   ;; type specification
+   FunFactorPresent ::= BOOLEAN
+
+   ;; values declaration and assignment
+   pythonFunFactor FunFactorPresent ::= TRUE
+   cobolFunFactor FunFactorPresent :: FALSE
+
+And here's pyasn1 version of :py:class:`~pyasn1.type.univ.Boolean`:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> class FunFactorPresent(univ.Boolean): pass
+   ... 
+   >>> pythonFunFactor = FunFactorPresent(True)
+   >>> cobolFunFactor = FunFactorPresent(False)
+   >>> pythonFunFactor
+   FunFactorPresent('True(1)')
+   >>> cobolFunFactor
+   FunFactorPresent('False(0)')
+   >>> pythonFunFactor == cobolFunFactor
+   False
+   >>>
+
+Null type
++++++++++
+
+The *NULL* type is sometimes used to express the absense of
+information.
+
+.. code-block:: bash
+
+   ;; type specification
+   Vote ::= CHOICE {
+     agreed BOOLEAN,
+     skip NULL
+   }
+
+   ;; value declaration and assignment
+   myVote Vote ::= skip:NULL
+
+We will explain the CHOICE type later on, meanwhile the
+:py:class:`~pyasn1.type.univ.Null` type:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> skip = univ.Null()
+   >>> skip
+   Null('')
+   >>>
+
+Integer type
+++++++++++++
+
+ASN.1 defines the values of *INTEGER* type as negative or positive of
+whatever length. This definition plays nicely with Python as the
+latter places no limit on Integers. However, some ASN.1
+implementations may impose certain limits of integer value ranges.
+Keep that in mind when designing new data structures.
+
+.. code-block:: bash
+
+   ;; values specification
+   age-of-universe INTEGER ::= 13750000000
+   mean-martian-surface-temperature INTEGER ::= -63
+
+A rather strigntforward mapping into pyasn1 -
+:py:class:`~pyasn1.type.univ.Integer`:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> ageOfUniverse = univ.Integer(13750000000)
+   >>> ageOfUniverse
+   Integer(13750000000)
+   >>>
+   >>> meanMartianSurfaceTemperature = univ.Integer(-63)
+   >>> meanMartianSurfaceTemperature
+   Integer(-63)
+   >>>
+
+ASN.1 allows to assign human-friendly names to particular values of
+an INTEGER type.
+
+.. code-block:: bash
+
+   Temperature ::= INTEGER {
+     freezing(0),
+     boiling(100)
+   }
+
+The Temperature type expressed in pyasn1:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedval
+   >>> class Temperature(univ.Integer):
+   ...   namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
+   ...
+   >>> t = Temperature(0)
+   >>> t
+   Temperature('freezing(0)')
+   >>> t + 1
+   Temperature(1)
+   >>> t + 100
+   Temperature('boiling(100)')
+   >>> t = Temperature('boiling')
+   >>> t
+   Temperature('boiling(100)')
+   >>> Temperature('boiling') / 2
+   Temperature(50)
+   >>> -1 < Temperature('freezing')
+   True
+   >>> 47 > Temperature('boiling')
+   False
+
+These values labels have no effect on Integer type operations, any value
+still could be assigned to a type (information on value constraints will
+follow further in the documentation).
+
+Enumerated type
++++++++++++++++
+
+ASN.1 *ENUMERATED* type differs from an Integer type in a number of
+ways.  Most important is that its instance can only hold a value that
+belongs to a set of values specified on type declaration.
+
+.. code-block:: bash
+
+   error-status ::= ENUMERATED {
+     no-error(0),
+     authentication-error(10),
+     authorization-error(20),
+     general-failure(51)
+   }
+
+When constructing :py:class:`~pyasn1.type.univ.Enumerated` type we
+will use two pyasn1 features: values labels (as mentioned above) and
+value constraint (will be described in more details later on).
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedval, constraint
+   >>> class ErrorStatus(univ.Enumerated):
+   ...   namedValues = namedval.NamedValues(
+   ...        ('no-error', 0),
+   ...        ('authentication-error', 10),
+   ...        ('authorization-error', 20),
+   ...        ('general-failure', 51)
+   ...   )
+   ...   subtypeSpec = univ.Enumerated.subtypeSpec + \
+   ...                    constraint.SingleValueConstraint(0, 10, 20, 51)
+   ...
+   >>> errorStatus = univ.ErrorStatus('no-error')
+   >>> errorStatus
+   ErrorStatus('no-error(0)')
+   >>> errorStatus == univ.ErrorStatus('general-failure')
+   False
+   >>> univ.ErrorStatus('non-existing-state')
+   Traceback (most recent call last):
+   ...
+   pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
+   >>>
+
+Particular integer values associated with Enumerated value states have
+no meaning. They should not be used as such or in any kind of math
+operation. Those integer values are only used by codecs to transfer
+state from one entity to another.
+
+Real type
++++++++++
+
+Values of the *REAL* type are a three-component tuple of mantissa,
+base and exponent. All three are integers.
+
+.. code-block:: bash
+
+   pi ::= REAL { mantissa 314159, base 10, exponent -5 }
+
+Corresponding pyasn1 :py:class:`~pyasn1.type.univ.Real` objects can be
+initialized with either a three-component tuple or a Python float.
+Infinite values could be expressed in a way, compatible with Python
+float type.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> pi = univ.Real((314159, 10, -5))
+   >>> pi
+   Real((314159, 10,-5))
+   >>> float(pi)
+   3.14159
+   >>> pi == univ.Real(3.14159)
+   True
+   >>> univ.Real('inf')
+   Real('inf')
+   >>> univ.Real('-inf') == float('-inf')
+   True
+   >>>
+
+If a Real object is initialized from a Python float or yielded by a math
+operation, the base is set to decimal 10 (what affects encoding).
+
+Bit string type
++++++++++++++++
+
+ASN.1 *BIT STRING* type holds opaque binary data of an arbitrarily
+length.  A BIT STRING value could be initialized by either a binary
+(base 2) or hex (base 16) value.
+
+.. code-block:: bash
+
+   public-key BIT STRING ::= '1010111011110001010110101101101
+                              1011000101010000010110101100010
+                              0110101010000111101010111111110'B
+
+   signature  BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
+
+The pyasn1 :py:class:`~pyasn1.type.univ.BitString` objects can
+initialize from native ASN.1 notation (base 2 or base 16 strings) or
+from a Python tuple of binary components.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> publicKey = univ.BitString(
+   ...          binValue='1010111011110001010110101101101'
+   ...                   '1011000101010000010110101100010'
+   ...                   '0110101010000111101010111111110'
+   )
+   >>> publicKey
+   BitString(binValue='101011101111000101011010110110110110001010100000101101011000100110101010000111101010111111110')
+   >>> signature = univ.BitString(
+   ...          hexValue='AF01330CD932093392100B39FF00DE0'
+   ... )
+   >>> signature
+   BitString(binValue='1010111100000001001100110000110011011001001100100000100100110011100100100001000000001011001110011111111100000000110111100000')
+   >>> fingerprint = univ.BitString(
+   ...          (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
+   ... )
+   >>> fingerprint
+   BitString(binValue='101101110101')
+   >>>
+
+Another BIT STRING initialization method supported by ASN.1 notation
+is to specify only 1-th bits along with their human-friendly label and
+bit offset relative to the beginning of the bit string. With this
+method, all not explicitly mentioned bits are doomed to be zeros.
+
+.. code-block:: bash
+
+   bit-mask  BIT STRING ::= {
+     read-flag(0),
+     write-flag(2),
+     run-flag(4)
+   }
+
+To express this in pyasn1, we will employ the named values feature (as
+with Enumeration type).
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedval
+   >>> class BitMask(univ.BitString):
+   ...   namedValues = namedval.NamedValues(
+   ...        ('read-flag', 0),
+   ...        ('write-flag', 2),
+   ...        ('run-flag', 4)
+   ... )
+   >>> bitMask = BitMask('read-flag,run-flag')
+   >>> bitMask
+   BitMask(binValue='10001')
+   >>> tuple(bitMask)
+   (1, 0, 0, 0, 1)
+   >>> bitMask[4]
+   1
+   >>>
+
+The BitString objects mimic the properties of Python tuple type in
+part of immutable sequence object protocol support.
+
+OctetString type
+++++++++++++++++
+
+The *OCTET STRING* type is a confusing subject. According to ASN.1
+specification, this type is similar to BIT STRING, the major
+difference is that the former operates in 8-bit chunks of data. What
+is important to note, is that OCTET STRING was NOT designed to handle
+text strings - the standard provides many other types specialized for
+text content. For that reason, ASN.1 forbids to initialize OCTET
+STRING values with "quoted text strings", only binary or hex
+initializers, similar to BIT STRING ones, are allowed.
+
+.. code-block:: bash
+
+   thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
+   thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
+
+However, ASN.1 users (e.g. protocols designers) seem to ignore the
+original purpose of the OCTET STRING type - they used it for handling
+all kinds of data, including text strings.
+
+.. code-block:: bash
+
+   welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
+
+In pyasn1, we have taken a liberal approach and allowed both BIT
+STRING style and quoted text initializers for the
+:py:class:`~pyasn1.type.univ.OctetString` objects.  To avoid possible
+collisions, quoted text is the default initialization syntax.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> thumbnail = univ.OctetString(
+   ...    binValue='1000010111101110101111000000111011'
+   ... )
+   >>> thumbnail
+   OctetString(hexValue='85eebcec0')
+   >>> thumbnail = univ.OctetString(
+   ...    hexValue='FA9823C43E43510DE3422'
+   ... )
+   >>> thumbnail
+   OctetString(hexValue='fa9823c43e4351de34220')
+   >>>
+
+Most frequent usage of the OctetString class is to instantiate it with
+a text string.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
+   >>> welcomeMessage
+   OctetString(b'Welcome to ASN.1 wilderness!')
+   >>> print('%s' % welcomeMessage)
+   Welcome to ASN.1 wilderness!
+   >>> welcomeMessage[11:16]
+   OctetString(b'ASN.1')
+   >>> 
+
+OctetString objects support the immutable sequence object protocol.
+In other words, they behave like Python 3 bytes (or Python 2 strings).
+When running pyasn1 on Python 3, it's better to use the bytes objects for
+OctetString instantiation, as it's more reliable and efficient.
+
+Additionally, OctetString's can also be instantiated with a sequence of
+8-bit integers (ASCII codes).
+
+.. code-block:: pycon
+
+   >>> univ.OctetString((77, 101, 101, 103, 111))
+   OctetString(b'Meego')
+
+It is sometimes convenient to express OctetString instances as 8-bit
+characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
+
+.. code-block:: pycon
+
+   >>> octetString = univ.OctetString('ABCDEF')
+   >>> octetString.asNumbers()
+   (65, 66, 67, 68, 69, 70)
+   >>> octetString.asOctets()
+   b'ABCDEF'
+
+ObjectIdentifier type
++++++++++++++++++++++
+
+Values of the *OBJECT IDENTIFIER* type are sequences of integers that
+could be used to identify virtually anything in the world. Various
+ASN.1-based protocols employ OBJECT IDENTIFIERs for their own
+identification needs.
+
+.. code-block:: bash
+
+   internet-id OBJECT IDENTIFIER ::= {
+     iso(1) identified-organization(3) dod(6) internet(1)
+   }
+
+One of the natural ways to map OBJECT IDENTIFIER type into a Python
+one is to use Python tuples of integers. So this approach is taken by
+pyasn1's :py:class:`~pyasn1.type.univ.ObjectIdentifier` class.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
+   >>> internetId
+   ObjectIdentifier('1.3.6.1')
+   >>> internetId[2]
+   6
+   >>> internetId[1:3]
+   ObjectIdentifier('3.6')
+
+A more human-friendly "dotted" notation is also supported.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> univ.ObjectIdentifier('1.3.6.1')
+   ObjectIdentifier('1.3.6.1')
+
+Symbolic names of the arcs of object identifier, sometimes present in
+ASN.1 specifications, are not preserved and used in pyasn1 objects.
+
+The ObjectIdentifier objects mimic the properties of Python tuple type in
+part of immutable sequence object protocol support.
+
+Any type
+++++++++
+
+The ASN.1 ANY type is a kind of wildcard or placeholder that matches
+any other type without knowing it in advance. ANY has no base tag.
+
+.. code-block:: bash
+
+   Error ::= SEQUENCE {
+     code      INTEGER,
+     parameter ANY DEFINED BY code
+   }
+
+The ANY type is frequently used in specifications, where exact type is
+not yet agreed upon between communicating parties or the number of
+possible alternatives of a type is infinite.  Sometimes an auxiliary
+selector is kept around to help parties indicate the kind of ANY
+payload in effect ("code" in the example above).
+
+Values of the ANY type contain serialized ASN.1 value(s) in form of an
+octet string. Therefore pyasn1 :py:class:`~pyasn1.type.univ.Any` value
+object share the properties of pyasn1 OctetString object.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> someValue = univ.Any(b'\x02\x01\x01')
+   >>> someValue
+   Any(b'\x02\x01\x01')
+   >>> str(someValue)
+   '\x02\x01\x01'
+   >>> bytes(someValue)
+   b'\x02\x01\x01'
+   >>>
+
+Receiving application is supposed to explicitly deserialize the
+content of Any value object, possibly using auxiliary selector for
+figuring out its ASN.1 type to pick appropriate decoder.
+
+There will be some more talk and code snippets covering Any type in
+the codecs chapters that follow.
+
+Character string types
+++++++++++++++++++++++
+
+ASN.1 standard introduces a diverse set of text-specific types. All of
+them were designed to handle various types of characters. Some of
+these types seem be obsolete nowdays, as their target technologies are
+gone. Another issue to be aware of is that raw OCTET STRING type is
+sometimes used in practice by ASN.1 users instead of specialized
+character string types, despite explicit prohibition imposed by ASN.1
+specification.
+
+The two types are specific to ASN.1 are NumericString and PrintableString.
+
+.. code-block:: bash
+
+   welcome-message ::= PrintableString {
+     "Welcome to ASN.1 text types"
+   }
+
+   dial-pad-numbers ::= NumericString {
+     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+   }
+
+Their pyasn1 implementations are
+:py:class:`~pyasn1.type.char.PrintableString` and
+:py:class:`~pyasn1.type.char.NumericString`:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char
+   >>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
+   'Welcome to ASN.1 text types'
+   >>> dialPadNumbers = char.NumericString(
+     "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
+   )
+   >>> dialPadNumbers
+   NumericString(b'0123456789')
+   >>>
+
+The :py:class:`~pyasn1.type.char.VisibleString`,
+:py:class:`~pyasn1.type.char.IA5String`,
+:py:class:`~pyasn1.type.char.TeletexString`,
+:py:class:`~pyasn1.type.char.VideotexString`,
+:py:class:`~pyasn1.type.char.GraphicString` and
+:py:class:`~pyasn1.type.char.GeneralString` types came to ASN.1 from
+ISO standards on character sets.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char
+   >>> char.VisibleString("abc")
+   VisibleString(b'abc')
+   >>> char.IA5String('abc')
+   IA5String(b'abc')
+   >>> char.TeletexString('abc')
+   TeletexString(b'abc')
+   >>> char.VideotexString('abc')
+   VideotexString(b'abc')
+   >>> char.GraphicString('abc')
+   GraphicString(b'abc')
+   >>> char.GeneralString('abc')
+   GeneralString(b'abc')
+   >>>
+
+The last three types are relatively recent addition to the family of
+character string types: :py:class:`~pyasn1.type.char.UniversalString`,
+:py:class:`~pyasn1.type.char.BMPString` and
+:py:class:`~pyasn1.type.char.UTF8String`.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char
+   >>> char.UniversalString("abc")
+   UniversalString(b'abc')
+   >>> char.BMPString('abc')
+   BMPString(b'abc')
+   >>> char.UTF8String('abc')
+   UTF8String(b'abc')
+   >>> utf8String = char.UTF8String('У попа была собака')
+   >>> utf8String
+   UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0\xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
+   >>> print(utf8String)
+   У попа была собака
+   >>>
+
+In pyasn1, all character type objects behave like Python strings. None
+of them is currently constrained in terms of valid alphabet so it's up
+to the data source to keep an eye on data validation for these types.
+
+Useful types
+++++++++++++
+
+There are three so-called useful types defined in the standard:
+:py:class:`~pyasn1.type.useful.ObjectDescriptor`,
+:py:class:`~pyasn1.type.useful.GeneralizedTime` and
+:py:class:`~pyasn1.type.useful.UTCTime`. They all are subtypes of
+GraphicString or VisibleString types therefore useful types are
+character string types.
+
+It's advised by the ASN.1 standard to have an instance of
+ObjectDescriptor type holding a human-readable description of
+corresponding instance of OBJECT IDENTIFIER type. There are no formal
+linkage between these instances and provision for ObjectDescriptor
+uniqueness in the standard.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import useful
+   >>> descrBER = useful.ObjectDescriptor(
+         "Basic encoding of a single ASN.1 type"
+   )
+   >>> 
+
+GeneralizedTime and UTCTime types are designed to hold a
+human-readable timestamp in a universal and unambiguous form. The
+former provides more flexibility in notation while the latter is more
+strict but has Y2K issues.
+
+.. code-block:: bash
+
+   ;; Mar 8 2010 12:00:00 MSK
+   moscow-time GeneralizedTime ::= "20110308120000.0"
+   ;; Mar 8 2010 12:00:00 UTC
+   utc-time GeneralizedTime ::= "201103081200Z"
+   ;; Mar 8 1999 12:00:00 UTC
+   utc-time UTCTime ::= "9803081200Z"
+
+In pyasn1 parlance:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import useful
+   >>> moscowTime = useful.GeneralizedTime("20110308120000.0")
+   >>> utcTime = useful.UTCTime("9803081200Z")
+   >>> 
+
+Despite their intended use, these types possess no special, time-related,
+handling in pyasn1. They are just printable strings.
+
+Tagging
+-------
+
+In order to proceed to the Constructed ASN.1 types, we will first have
+to introduce the concept of tagging (and its pyasn1 implementation), as
+some of the Constructed types rely upon the tagging feature.
+
+When a value is coming into an ASN.1-based system (received from a network
+or read from some storage), the receiving entity has to determine the
+type of the value to interpret and verify it accordingly.
+
+Historically, the first data serialization protocol introduced in
+ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
+value is packed into a triplet of (Type, Length, Value) where Type is a 
+code that identifies the value (which is called *tag* in ASN.1),
+length is the number of bytes occupied by the value in its serialized form
+and value is ASN.1 value in a form suitable for serial transmission or storage.
+For that reason almost every ASN.1 type has a tag (which is actually a
+BER type) associated with it by default.
+
+An ASN.1 tag could be viewed as a tuple of three numbers:
+(Class, Format, Number). While Number identifies a tag, Class component 
+is used to create scopes for Numbers. Four scopes are currently defined:
+UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
+is actually a one-bit flag - zero for tags associated with scalar types,
+and one for constructed types (will be discussed later on).
+
+.. code-block:: bash
+
+   MyIntegerType ::= [12] INTEGER
+   MyOctetString ::= [APPLICATION 0] OCTET STRING
+
+In pyasn1, tags are implemented as immutable, tuple-like objects:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import tag
+   >>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+   >>> myTag
+   Tag(tagClass=128, tagFormat=0, tagId=10)
+   >>> tuple(myTag)
+   (128, 0, 10)
+   >>> myTag[2]
+   10
+   >>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
+   False
+   >>>
+
+Default tag, associated with any ASN.1 type, could be extended or
+replaced to make new type distinguishable from its ancestor. The
+standard provides two modes of tag mangling - IMPLICIT and EXPLICIT.
+
+EXPLICIT mode works by appending new tag to the existing ones thus
+creating an ordered set of tags. This set will be considered as a
+whole for type identification and encoding purposes. Important
+property of EXPLICIT tagging mode is that it preserves base type
+information in encoding what makes it possible to completely recover
+type information from encoding.
+
+When tagging in IMPLICIT mode, the outermost existing tag is dropped
+and replaced with a new one.
+
+.. code-block:: bash
+
+   MyIntegerType ::= [12] IMPLICIT INTEGER
+   MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
+
+To model both modes of tagging, a specialized container TagSet object
+(holding zero, one or more Tag objects) is used in pyasn1.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import tag
+   >>> tagSet = tag.TagSet(
+   ...   # base tag (OBSOLETE AND NOT USED ANYMORE)
+   ...   (),
+   ...   # effective tag
+   ...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+   ... )
+   >>> tagSet
+   TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10))
+   >>> tagSet.getBaseTag()
+   Tag(tagClass=128, tagFormat=0, tagId=10)
+   >>> tagSet = tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20))
+   >>> tagSet
+   TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10), 
+   Tag(tagClass=128, tagFormat=32, tagId=20))
+   >>> tagSet = tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30))
+   >>> tagSet
+   TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10), 
+   Tag(tagClass=128, tagFormat=32, tagId=20), 
+   Tag(tagClass=128, tagFormat=32, tagId=30))
+   >>> tagSet = tagSet.tagImplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40))
+   >>> tagSet
+   TagSet((), Tag(tagClass=128, tagFormat=0, tagId=10),
+   Tag(tagClass=128, tagFormat=32, tagId=20),
+   Tag(tagClass=128, tagFormat=32, tagId=40))
+   >>> 
+
+As a side note: the "base tag" concept is now obsolete and not used.
+The "effective tag" is the one that always appears in encoding and is
+used on tagSets comparation.
+
+Any two TagSet objects could be compared to see if one is a derivative
+of the other. Figuring this out is also useful in cases when a type-specific
+data processing algorithms are to be chosen.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import tag
+   >>> tagSet1 = tag.TagSet(
+   ...   # base tag (OBSOLETE AND NOT USED ANYMORE)
+   ...   (),
+   ...   # effective tag
+   ...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
+   ... )
+   >>> tagSet2 = tagSet1.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20))
+   >>> tagSet1.isSuperTagSetOf(tagSet2)
+   True
+   >>> tagSet2.isSuperTagSetOf(tagSet1)
+   False
+   >>> 
+
+We will complete this discussion on tagging with a real-world example. The
+following ASN.1 tagged type:
+
+.. code-block:: bash
+
+   MyIntegerType ::= [12] EXPLICIT INTEGER
+
+could be expressed in pyasn1 like this:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, tag
+   >>> class MyIntegerType(univ.Integer):
+   ...   tagSet = univ.Integer.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12))
+   >>> myInteger = MyIntegerType(12345)
+   >>> myInteger.tagSet
+   TagSet((), Tag(tagClass=0, tagFormat=0, tagId=2), 
+   Tag(tagClass=128, tagFormat=32, tagId=12))
+   >>>
+
+Referring to the above code, the tagSet class attribute is a property
+of any pyasn1 type object that assigns default tagSet to a pyasn1
+value object. This default tagSet specification can be ignored and
+effectively replaced by some other tagSet value passed on object
+instantiation.
+
+It's important to understand that the tag set property of pyasn1 type/value
+object can never be modifed in place. In other words, a pyasn1 type/value
+object can never change its tags. The only way is to create a new pyasn1
+type/value object and associate different tag set with it.
+
+Constructed types
+-----------------
+
+Besides scalar types, ASN.1 specifies so-called constructed ones - these
+are capable of holding one or more values of other types, both scalar
+and constructed.
+
+In pyasn1 implementation, constructed ASN.1 types behave like 
+Python sequences, and also support additional component addressing methods,
+specific to particular constructed type.
+
+Sequence and Set types
+++++++++++++++++++++++
+
+The *SEQUENCE* and *SET* types have many similar properties:
+
+* Both can hold any number of inner components of different types.
+* Every component has a human-friendly identifier.
+* Any component can have a default value.
+* Some components can be absent.
+
+However, :py:class:`~pyasn1.type.univ.Sequence` type guarantees the
+ordering of Sequence value components to match their declaration
+order. By contrast, components of the
+:py:class:`~pyasn1.type.univ.Set` type can be ordered to best suite
+application's needs.
+
+.. code-block:: bash
+
+   Record ::= SEQUENCE {
+     id        INTEGER,
+     room  [0] INTEGER OPTIONAL,
+     house [1] INTEGER DEFAULT 0
+   }
+
+Up to this moment, the only method we used for creating new pyasn1
+types is Python sub-classing. With this method, a new, named Python
+class is created what mimics type derivation in ASN.1 grammar.
+However, ASN.1 also allows for defining anonymous subtypes (room and
+house components in the example above).  To support anonymous
+subtyping in pyasn1, a cloning operation on an existing pyasn1 type
+object can be invoked what creates a new instance of original object
+with possibly modified properties.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedtype, tag
+   >>> class Record(univ.Sequence):
+   ...   componentType = namedtype.NamedTypes(
+   ...     namedtype.NamedType('id', univ.Integer()),
+   ...     namedtype.OptionalNamedType(
+   ...       'room',
+   ...       univ.Integer().subtype(
+   ...         implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
+   ...       )
+   ...     ),
+   ...     namedtype.DefaultedNamedType(
+   ...       'house', 
+   ...       univ.Integer(0).subtype(
+   ...         implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
+   ...       )
+   ...     )
+   ...   )
+   >>>
+
+All pyasn1 constructed type classes have a class attribute
+**componentType** that represent default type specification. Its
+value is a NamedTypes object.
+
+The NamedTypes class instance holds a sequence of NameType,
+OptionalNamedType or DefaultedNamedType objects which, in turn, refer
+to pyasn1 type objects that represent inner SEQUENCE components
+specification.
+
+Finally, invocation of a subtype() method of pyasn1 type objects in
+the code above returns an implicitly tagged copy of original object.
+
+Once a SEQUENCE or SET type is decleared with pyasn1, it can be
+instantiated and initialized (continuing the above code):
+
+.. code-block:: pycon
+
+   >>> record = Record()
+   >>> record['id'] = 123
+   >>> print(record.prettyPrint())
+   Record:
+    id=123
+   >>> 
+   >>> record[1] = 321
+   >>> print(record.prettyPrint())
+   Record:
+    id=123
+    room=321
+   >>>
+   >>> record.setDefaultComponents()
+   >>> print(record.prettyPrint())
+   Record:
+    id=123
+    room=321
+    house=0
+
+Inner components of pyasn1 Sequence/Set objects could be accessed
+using the following methods:
+
+.. code-block:: pycon
+
+   >>> record['id']
+   Integer(123)
+   >>> record[1]
+   Integer(321)
+   >>> record[2]
+   Integer(0)
+   >>> for idx, field in enumerate(record):
+   ...   print(record.componentType[idx].name, field)
+   id 123
+   room 321
+   house 0
+   >>>
+
+The Set type share all the properties of Sequence type, and additionally
+support by-tag component addressing (as all Set components have distinct
+types).
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedtype, tag
+   >>> class Gamer(univ.Set):
+   ...   componentType = namedtype.NamedTypes(
+   ...     namedtype.NamedType('score', univ.Integer()),
+   ...     namedtype.NamedType('player', univ.OctetString()),
+   ...     namedtype.NamedType('id', univ.ObjectIdentifier())
+   ...   )
+   >>> gamer = Gamer()
+   >>> gamer.setComponentByType(univ.Integer().tagSet, 121343)
+   >>> gamer.setComponentByType(univ.OctetString().tagSet, 'Pascal')
+   >>> gamer.setComponentByType(univ.ObjectIdentifier().tagSet, (1,3,7,2))
+   >>> print(gamer.prettyPrint())
+   Gamer:
+    score=121343
+    player=b'Pascal'
+    id=1.3.7.2
+
+SequenceOf and SetOf types
+++++++++++++++++++++++++++
+
+Both, *SEQUENCE OF* and *SET OF* types resemble an unlimited size list of
+components.  All the components must be of the same type.
+
+.. code-block:: bash
+
+   Progression ::= SEQUENCE OF INTEGER
+
+   arithmeticProgression Progression ::= { 1, 3, 5, 7 }
+
+:py:class:`~pyasn1.type.univ.SequenceOf` and
+:py:class:`~pyasn1.type.univ.SetOf` types are expressed by the very
+similar pyasn1 `list` type objects. Their components can only be addressed by
+position and they both have a property of automatic resize.
+
+To specify inner component type, the **componentType** class
+attribute should refer to another pyasn1 type object.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> class Progression(univ.SequenceOf):
+   ...   componentType = univ.Integer()
+   >>> arithmeticProgression = Progression()
+   >>> arithmeticProgression[1] = 111
+   >>> print(arithmeticProgression.prettyPrint())
+   Progression:
+   -empty- 111
+   >>> arithmeticProgression[0] = 100
+   >>> print(arithmeticProgression.prettyPrint())
+   Progression:
+   100 111
+   >>>
+   >>> for element in arithmeticProgression:
+   ...    element
+   Integer(100)
+   Integer(111)
+   >>>
+
+Any scalar or constructed pyasn1 type object can serve as an inner
+component.  Missing components are prohibited in SequenceOf/SetOf
+value objects.
+
+Choice type
++++++++++++
+
+Values of ASN.1 *CHOICE* type can contain only a single value of a type
+from a list of possible alternatives. Alternatives must be ASN.1 types
+with distinct tags for the whole structure to remain unambiguous.
+Unlike most other types, CHOICE is an untagged one, e.g. it has no
+base tag of its own.
+
+.. code-block:: bash
+
+   CodeOrMessage ::= CHOICE {
+     code    INTEGER,
+     message OCTET STRING
+   }
+
+In pyasn1 implementation,
+:py:class:`~pyasn1.type.univ.Choice` object behaves like Set but
+accepts only a single inner component at a time. It also offers a few
+additional methods specific to its behaviour.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedtype
+   >>> class CodeOrMessage(univ.Choice):
+   ...   componentType = namedtype.NamedTypes(
+   ...     namedtype.NamedType('code', univ.Integer()),
+   ...     namedtype.NamedType('message', univ.OctetString())
+   ...   )
+   >>>
+   >>> codeOrMessage = CodeOrMessage()
+   >>> print(codeOrMessage.prettyPrint())
+   CodeOrMessage:
+   >>> codeOrMessage['code'] = 123
+   >>> print(codeOrMessage.prettyPrint())
+   CodeOrMessage:
+    code=123
+   >>> codeOrMessage['message'] = 'my string value'
+   >>> print(codeOrMessage.prettyPrint())
+   CodeOrMessage:
+    message=b'my string value'
+   >>>
+
+Since there could be only a single inner component value in the pyasn1
+Choice value object, either of the following methods could be used for
+fetching it (continuing previous code):
+
+.. code-block:: pycon
+
+   >>> codeOrMessage.getName()
+   'message'
+   >>> codeOrMessage.getComponent()
+   OctetString(b'my string value')
+   >>>
+
+Subtype constraints
+-------------------
+
+Most ASN.1 types can correspond to an infinite set of values. To adapt
+to particular application's data model and needs, ASN.1 provides a
+mechanism for limiting the infinite set to values, that make sense in
+particular case.  Imposing value constraints on an ASN.1 type can also
+be seen as creating a subtype from its base type.
+
+In pyasn1, constraints take shape of immutable objects capable
+of evaluating given value against constraint-specific requirements.
+Constraint object is a property of pyasn1 type. Like TagSet property,
+associated with every pyasn1 type, constraints can never be modified
+in place. The only way to modify pyasn1 type constraint is to associate
+new constraint object to a new pyasn1 type object.
+
+A handful of different flavors of *constraints* are defined in
+ASN.1.  We will discuss them one by one in the following chapters and
+also explain how to combine and apply them to types.
+
+Single value constraint
++++++++++++++++++++++++
+
+This kind of constraint allows for limiting type to a finite, specified set
+of values.
+
+.. code-block:: bash
+
+   DialButton ::= OCTET STRING (
+     "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+   )
+
+Its pyasn1 implementation would look like:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import constraint
+   >>> c = constraint.SingleValueConstraint('0','1','2','3','4','5','6','7','8','9')
+   >>> c
+   SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+   >>> c('0')
+   >>> c('A')
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+   >>>
+
+As can be seen in the snippet above, if a value violates the
+constraint, an exception will be thrown. A constrainted pyasn1 type
+object holds a reference to a constraint object (or their combination,
+as will be explained later) and calls it for value verification.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> class DialButton(univ.OctetString):
+   ...   subtypeSpec = constraint.SingleValueConstraint(
+   ...       '0','1','2','3','4','5','6','7','8','9'
+   ...   )
+   >>> DialButton('0')
+   DialButton(b'0')
+   >>> DialButton('A')
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+   >>> 
+
+Constrained pyasn1 value object can never hold a violating value.
+
+Value range constraint
+++++++++++++++++++++++
+
+A pair of values, compliant to a type to be constrained, denote low
+and upper bounds of allowed range of values of a type.
+
+.. code-block:: bash
+
+   Teenagers ::= INTEGER (13..19)
+
+And in pyasn1 terms:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> class Teenagers(univ.Integer):
+   ...   subtypeSpec = constraint.ValueRangeConstraint(13, 19)
+   >>> Teenagers(14)
+   Teenagers(14)
+   >>> Teenagers(20)
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     ValueRangeConstraint(13, 19) failed at: 20
+   >>> 
+
+ASN.1 MIN and MAX operands can be substituted with floating point
+infinity values.
+
+.. code-block:: bash
+
+   NegativeInt ::= INTEGER (MIN..-1)
+   PositiveInt ::= INTEGER (1..MAX)
+
+And in pyasn1 terms:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> class NegativeInt(univ.Integer):
+   ...   subtypeSpec = constraint.ValueRangeConstraint(float('-inf'), -1)
+   >>> NegativeInt(-1)
+   NegativeInt(-1)
+   >>> NegativeInt(0)
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     ValueConstraintError: ValueRangeConstraint() failed at: "0" at NegativeInt
+   >>> class PositiveInt(univ.Integer):
+   ...   subtypeSpec = constraint.ValueRangeConstraint(1, float('inf'))
+   >> PositiveInt(1)
+   PositiveInt(1)
+   >> PositiveInt(4)
+   PositiveInt(4)
+   >> PositiveInt(-1)
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     ValueConstraintError: ValueRangeConstraint() failed at: "-1" at PositiveInt
+
+Value range constraint usually applies to numeric types.
+
+Size constraint
++++++++++++++++
+
+It is sometimes convenient to set or limit the allowed size of a data
+item to be sent from one application to another to manage bandwidth
+and memory consumption issues. Size constraint specifies the lower and
+upper bounds of the size of a valid value.
+
+.. code-block:: bash
+
+   TwoBits ::= BIT STRING (SIZE (2))
+
+Express the same grammar in pyasn1:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> class TwoBits(univ.BitString):
+   ...   subtypeSpec = constraint.ValueSizeConstraint(2, 2)
+   >>> TwoBits((1,1))
+   TwoBits("'11'B")
+   >>> TwoBits((1,1,0))
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError: ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
+   >>> 
+
+Size constraint can be applied to potentially massive values - bit or
+octet strings, SEQUENCE OF/SET OF values.
+
+Alphabet constraint
++++++++++++++++++++
+
+The permitted alphabet constraint is similar to Single value
+constraint but constraint applies to individual characters of a value. 
+
+.. code-block:: bash
+
+   MorseCode ::= PrintableString (FROM ("."|"-"|" "))
+
+And in pyasn1:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char, constraint
+   >>> class MorseCode(char.PrintableString):
+   ...   subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
+   >>> MorseCode("...---...")
+   MorseCode('...---...')
+   >>> MorseCode("?")
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError: PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
+   >>> 
+
+Current implementation does not handle ranges of characters in
+constraint (FROM "A".."Z" syntax), one has to list the whole set in a
+range.
+
+Constraint combinations
++++++++++++++++++++++++
+
+Up to this moment, we used a single constraint per ASN.1 type. The
+standard, however, allows for combining multiple individual
+constraints into intersections, unions and exclusions.
+
+In pyasn1 data model, all of these methods of constraint combinations
+are implemented as constraint-like objects holding individual
+constraint (or combination) objects. Like terminal constraint objects,
+combination objects are capable to perform value verification at its
+set of enclosed constraints according to the logic of particular
+combination.
+
+Constraints intersection verification succeeds only if a value is
+compliant to each constraint in a set. To begin with, the following
+specification will constitute a valid telephone number:
+
+.. code-block:: bash
+
+   PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
+
+Constraint intersection object serves the logic above:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char, constraint
+   >>> class PhoneNumber(char.NumericString):
+   ...   subtypeSpec = constraint.ConstraintsIntersection(
+   ...     constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6', '7','8','9'),
+   ...     constraint.ValueSizeConstraint(11, 11)
+   ...   )
+   >>> PhoneNumber('79039343212')
+   PhoneNumber('79039343212')
+   >>> PhoneNumber('?9039343212')
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError: ConstraintsIntersection(PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'), ValueSizeConstraint(11, 11)) failed at: PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
+   >>> PhoneNumber('9343212')
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     ConstraintsIntersection(PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'), ValueSizeConstraint(11, 11)) failed at: ValueSizeConstraint(10, 10) failed at: "9343212"
+   >>>
+
+Union of constraints works by making sure that a value is compliant
+to any of the constraint in a set. For instance:
+
+.. code-block:: bash
+
+   CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
+
+It's important to note, that a value must fully comply to any single
+constraint in a set. In the specification above, a value of all small
+or all capital letters is compliant, but a mix of small&capitals is
+not.  Here's its pyasn1 analogue:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import char, constraint
+   >>> class CapitalOrSmall(char.IA5String):
+   ...   subtypeSpec = constraint.ConstraintsUnion(
+   ...     constraint.PermittedAlphabetConstraint('A','B','C'),
+   ...     constraint.PermittedAlphabetConstraint('a','b','c')
+   ...   )
+   >>> CapitalOrSmall('ABBA')
+   CapitalOrSmall('ABBA')
+   >>> CapitalOrSmall('abba')
+   CapitalOrSmall('abba')
+   >>> CapitalOrSmall('Abba')
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError: ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'), PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
+   >>>
+
+Finally, the exclusion constraint simply negates the logic of value
+verification at a constraint. In the following example, any integer
+value is allowed in a type but not zero.
+
+.. code-block:: bash
+
+   NoZero ::= INTEGER (ALL EXCEPT 0)
+
+In pyasn1 the above definition would read:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> class NoZero(univ.Integer):
+   ...   subtypeSpec = constraint.ConstraintsExclusion(
+   ...     constraint.SingleValueConstraint(0)
+   ...   )
+   >>> NoZero(1)
+   NoZero(1)
+   >>> NoZero(0)
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError: ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
+   >>>
+
+The depth of such a constraints tree, built with constraint
+combination objects at its nodes, has not explicit limit. Value
+verification is performed in a recursive manner till a definite
+solution is found.
+
+Types relationships
++++++++++++++++++++
+
+In the course of data processing in an application, it is sometimes
+convenient to figure out the type relationships between pyasn1 type or
+value objects. Formally, two things influence pyasn1 types
+relationship: *tag set* and *subtype constraints*. One
+pyasn1 type is considered to be a derivative of another if their
+TagSet and Constraint objects are a derivation of one another.
+
+The following example illustrates the concept (we use the same tagset
+but different constraints for simplicity):
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
+   >>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
+   ...    constraint.ValueRangeConstraint(3,8),
+   ...    constraint.ValueRangeConstraint(4,7)
+   ... ) )
+   >>> i1.isSameTypeWith(i2)
+   False
+   >>> i1.isSuperTypeOf(i2)
+   True
+   >>> i1.isSuperTypeOf(i1)
+   True
+   >>> i2.isSuperTypeOf(i1)
+   False
+   >>>
+
+As can be seen in the above code snippet, there are two methods of any
+pyasn1 type/value object that test types for their relationship:
+*isSameTypeWith()* and *isSuperTypeOf()*. The former is
+self-descriptive while the latter yields true if the argument appears
+to be a pyasn1 object which has tagset and constraints derived from
+those of the object being called.
+
+Serialization codecs
+--------------------
+
+In ASN.1 context, `codec <http://en.wikipedia.org/wiki/Codec>`_
+is a program that transforms between concrete data structures and a stream
+of octets, suitable for transmission over the wire. This serialized form of
+data is sometimes called *substrate* or *essence*.
+
+In pyasn1 implementation, substrate takes shape of Python 3 bytes or 
+Python 2 string objects.
+
+One of the properties of a codec is its ability to cope with
+incomplete data and/or substrate what implies codec to be stateful. In
+other words, when decoder runs out of substrate and data item being
+recovered is still incomplete, stateful codec would suspend and
+complete data item recovery whenever the rest of substrate becomes
+available. Similarly, stateful encoder would encode data items in
+multiple steps waiting for source data to arrive. Codec restartability
+is especially important when application deals with large volumes of
+data and/or runs on low RAM. For an interesting discussion on codecs
+options and design choices, refer to `Apache ASN.1 project
+<http://directory.apache.org/subprojects/asn1/>`_ .
+
+As of this writing, codecs implemented in pyasn1 are all stateless,
+mostly to keep the code simple.
+
+The pyasn1 package currently supports 
+`BER <http://en.wikipedia.org/wiki/Basic_encoding_rules>`_ codec and
+its variations -- 
+`CER <http://en.wikipedia.org/wiki/Canonical_encoding_rules>`_ and
+`DER <http://en.wikipedia.org/wiki/Distinguished_encoding_rules>`_.
+More ASN.1 codecs are planned for implementation in the future.
+
+Encoders
+++++++++
+
+Encoder is used for transforming pyasn1 value objects into substrate.
+Only pyasn1 value objects could be serialized, attempts to process
+pyasn1 type objects will cause encoder failure.
+
+The following code will create a pyasn1 Integer object and serialize
+it with BER encoder:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder
+   >>> encoder.encode(univ.Integer(123456))
+   b'\x02\x03\x01\xe2@'
+   >>>
+
+BER standard also defines a so-called *indefinite length*
+encoding form which makes large data items processing more memory
+efficient. It is mostly useful when encoder does not have the whole
+value all at once and the length of the value can not be determined at
+the beginning of encoding.
+
+*Constructed encoding* is another feature of BER closely related to
+the indefinite length form. In essence, a large scalar value (such as
+ASN.1 character BitString type) could be chopped into smaller chunks
+by encoder and transmitted incrementally to limit memory consumption.
+Unlike indefinite length case, the length of the whole value must be
+known in advance when using constructed, definite length encoding
+form.
+
+Since pyasn1 codecs are not restartable, pyasn1 encoder may only
+encode data item all at once. However, even in this case, generating
+indefinite length encoding may help a low-memory receiver, running a
+restartable decoder, to process a large data item.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder
+   >>> encoder.encode(
+   ...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
+   ...   defMode=False,
+   ...   maxChunkSize=8
+   ... )
+   b'$\x80\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \t\x04\x08he lazy \x04\x03dog\x00\x00'
+   >>>
+   >>> encoder.encode(
+   ...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
+   ...   maxChunkSize=8
+   ... )
+   b'$7\x04\x08The quic\x04\x08k brown \x04\x08fox jump\x04\x08s over \t\x04\x08he lazy \x04\x03dog'
+
+The *defMode* encoder parameter disables definite length encoding
+mode, while the optional *maxChunkSize* parameter specifies desired
+substrate chunk size that influences memory requirements at the
+decoder's end.
+
+To use CER or DER encoders one needs to explicitly import and call them - the
+APIs are all compatible.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder as ber_encoder
+   >>> from pyasn1.codec.cer import encoder as cer_encoder
+   >>> from pyasn1.codec.der import encoder as der_encoder
+   >>> ber_encoder.encode(univ.Boolean(True))
+   b'\x01\x01\x01'
+   >>> cer_encoder.encode(univ.Boolean(True))
+   b'\x01\x01\xff'
+   >>> der_encoder.encode(univ.Boolean(True))
+   b'\x01\x01\xff'
+   >>>
+
+Decoders
+++++++++
+
+In the process of decoding, pyasn1 value objects are created and
+linked to each other, based on the information containted in the
+substrate. Thus, the original pyasn1 value object(s) are recovered.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> substrate = encoder.encode(univ.Boolean(True))
+   >>> decoder.decode(substrate)
+   (Boolean('True(1)'), b'')
+   >>>
+
+Commenting on the code snippet above, pyasn1 decoder accepts substrate
+as an argument and returns a tuple of pyasn1 value object (possibly a
+top-level one in case of constructed object) and unprocessed part of
+input substrate.
+
+All pyasn1 decoders can handle both definite and indefinite length
+encoding modes automatically, explicit switching into one mode to
+another is not required.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> substrate = encoder.encode(
+   ...   univ.OctetString('The quick brown fox jumps over the lazy dog'),
+   ...   defMode=False,
+   ...   maxChunkSize=8
+   ... )
+   >>> decoder.decode(substrate)
+   (OctetString(b'The quick brown fox jumps over the lazy dog'), b'')
+   >>>
+
+Speaking of BER/CER/DER encoding, in many situations substrate may not
+contain all necessary information needed for complete and accurate
+ASN.1 values recovery. The most obvious cases include implicitly
+tagged ASN.1 types and constrained types.
+
+As discussed earlier in this tutorial, when an ASN.1 type is implicitly
+tagged, previous outermost tag is lost and never appears in substrate.
+If it is the base tag that gets lost, decoder is unable to pick type-specific
+value decoder at its table of built-in types, and therefore recover
+the value part, based only on the information contained in substrate. The
+approach taken by pyasn1 decoder is to use a prototype pyasn1 type object (or
+a set of them) to *guide* the decoding process by matching [possibly
+incomplete] tags recovered from substrate with those found in prototype pyasn1
+type objects (also called pyasn1 specification object further in this
+document).
+
+.. code-block:: pycon
+
+   >>> from pyasn1.codec.ber import decoder
+   >>> decoder.decode(b'\x02\x01\x0c', asn1Spec=univ.Integer())
+   Integer(12), b''
+   >>>
+
+Decoder would neither modify pyasn1 specification object nor use its
+current values (if it's a pyasn1 value object), but rather use it as a
+hint for choosing proper decoder and as a pattern for creating new
+objects:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, tag
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> i = univ.Integer(12345).subtype(
+   ...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
+   ... )
+   >>> substrate = encoder.encode(i)
+   >>> substrate
+   b'\x9f(\x0209'
+   >>> decoder.decode(substrate)
+   Traceback (most recent call last):
+   ...
+   pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40)) not in asn1Spec
+   >>> decoder.decode(substrate, asn1Spec=i)
+   (Integer(12345), b'')
+   >>>
+
+Notice in the example above, that an attempt to run decoder without
+passing pyasn1 specification object fails because recovered tag does
+not belong to any of the built-in types.
+
+Another important feature of guided decoder operation is the use of
+values constraints possibly present in pyasn1 specification object.
+To explain this, we will decode a random integer object into generic Integer
+and the constrained one.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, constraint
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> class DialDigit(univ.Integer):
+   ...   subtypeSpec = constraint.ValueRangeConstraint(0,9)
+   >>> substrate = encoder.encode(univ.Integer(13))
+   >>> decoder.decode(substrate)
+   (Integer(13), b'')
+   >>> decoder.decode(substrate, asn1Spec=DialDigit())
+   Traceback (most recent call last):
+   ...
+   ValueConstraintError:
+     ValueRangeConstraint(0, 9) failed at: 13
+   >>> 
+
+Similarily to encoders, to use CER or DER decoders application has to
+explicitly import and call them - all APIs are compatible.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder as ber_encoder
+   >>> substrate = ber_encoder.encode(univ.OctetString('http://pyasn1.sf.net'))
+   >>>
+   >>> from pyasn1.codec.ber import decoder as ber_decoder
+   >>> from pyasn1.codec.cer import decoder as cer_decoder
+   >>> from pyasn1.codec.der import decoder as der_decoder
+   >>> 
+   >>> ber_decoder.decode(substrate)
+   (OctetString(b'http://pyasn1.sf.net'), b'')
+   >>> cer_decoder.decode(substrate)
+   (OctetString(b'http://pyasn1.sf.net'), b'')
+   >>> der_decoder.decode(substrate)
+   (OctetString(b'http://pyasn1.sf.net'), b'')
+   >>> 
+
+Advanced topics
+---------------
+
+Certain, non-trivial, ASN.1 data structures may require special
+treatment, especially when running deserialization. 
+
+Decoding untagged types
++++++++++++++++++++++++
+
+It has already been mentioned, that ASN.1 has two "special case"
+types: CHOICE and ANY. They are different from other types in part of
+tagging - unless these two are additionally tagged, neither of them
+will have their own tag. Therefore these types become invisible in
+substrate and can not be recovered without passing pyasn1
+specification object to decoder.
+
+To explain the issue, we will first prepare a Choice object to deal with:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, namedtype
+   >>> class CodeOrMessage(univ.Choice):
+   ...   componentType = namedtype.NamedTypes(
+   ...     namedtype.NamedType('code', univ.Integer()),
+   ...     namedtype.NamedType('message', univ.OctetString())
+   ...   )
+   >>>
+   >>> codeOrMessage = CodeOrMessage()
+   >>> codeOrMessage['message'] = 'my string value'
+   >>> print(codeOrMessage.prettyPrint())
+   CodeOrMessage:
+    message=b'my string value'
+   >>>
+
+Let's now encode this Choice object and then decode its substrate
+with and without pyasn1 specification object:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> substrate = encoder.encode(codeOrMessage)
+   >>> substrate
+   b'\x04\x0fmy string value'
+   >>> encoder.encode(univ.OctetString('my string value'))
+   b'\x04\x0fmy string value'
+   >>>
+   >>> decoder.decode(substrate)
+   (OctetString(b'my string value'), b'')
+   >>> codeOrMessage, substrate = decoder.decode(substrate,
+   asn1Spec=CodeOrMessage())
+   >>> print(codeOrMessage.prettyPrint())
+   CodeOrMessage:
+    message=b'my string value'
+   >>>
+
+First thing to notice in the listing above is that the substrate
+produced for our Choice value object is equivalent to the substrate
+for an OctetString object initialized to the same value. In other
+words, any information about the Choice component is absent in
+encoding.
+
+Sure enough, that kind of substrate will decode into an OctetString
+object, unless original Choice type object is passed to decoder to
+guide the decoding process.
+
+Similarily untagged ANY type behaves differently on decoding phase -
+when decoder bumps into an Any object in pyasn1 specification, it
+stops decoding and puts all the substrate into a new Any value object
+in form of an octet string. Concerned application could then re-run
+decoder with an additional, more exact pyasn1 specification object to
+recover the contents of Any object.
+
+As it was mentioned elsewhere in this documentation, Any type allows
+for incomplete or changing ASN.1 specification to be handled
+gracefully by decoder and applications.
+
+To illustrate the working of Any type, we'll have to make the stage by
+encoding a pyasn1 object and then putting its substrate into an any
+object.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> innerSubstrate = encoder.encode(univ.Integer(1234))
+   >>> innerSubstrate
+   b'\x02\x02\x04\xd2'
+   >>> any = univ.Any(innerSubstrate)
+   >>> any
+   Any(b'\x02\x02\x04\xd2')
+   >>> substrate = encoder.encode(any)
+   >>> substrate
+   b'\x02\x02\x04\xd2'
+   >>>
+
+As with Choice type encoding, there is no traces of Any type in
+substrate.  Obviously, the substrate we are dealing with, will decode
+into the inner [Integer] component, unless pyasn1 specification is
+given to guide the decoder. Continuing previous code:
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ
+   >>> from pyasn1.codec.ber import encoder, decoder
+
+   >>> decoder.decode(substrate)
+   (Integer(1234), b'')
+   >>> any, substrate = decoder.decode(substrate, asn1Spec=univ.Any())
+   >>> any
+   Any(b'\x02\x02\x04\xd2')
+   >>> decoder.decode(str(any))
+   (Integer(1234), b'')
+   >>>
+
+Both CHOICE and ANY types are widely used in practice. Reader is welcome to
+take a look at 
+`ASN.1 specifications of X.509 applications
+<http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>`_
+for more information.
+
+Ignoring unknown types
+++++++++++++++++++++++
+
+When dealing with a loosely specified ASN.1 structure, the receiving
+end may not be aware of some types present in the substrate. It may be
+convenient then to turn decoder into a recovery mode. Whilst there,
+decoder will not bail out when hit an unknown tag but rather treat it
+as an Any type.
+
+.. code-block:: pycon
+
+   >>> from pyasn1.type import univ, tag
+   >>> from pyasn1.codec.ber import encoder, decoder
+   >>> taggedInt = univ.Integer(12345).subtype(
+   ...   implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
+   ... )
+   >>> substrate = encoder.encode(taggedInt)
+   >>> decoder.decode(substrate)
+   Traceback (most recent call last):
+   ...
+   pyasn1.error.PyAsn1Error: TagSet(Tag(tagClass=128, tagFormat=0, tagId=40))
+   not in asn1Spec
+   >>>
+   >>> decoder.decode.defaultErrorState = decoder.stDumpRawValue
+   >>> decoder.decode(substrate)
+   (Any(b'\x9f(\x0209'), '')
+   >>>
+
+It's also possible to configure a custom decoder, to handle unknown
+tags found in substrate. This can be done by means of
+*defaultRawDecoder* attribute holding a reference to type decoder
+object. Refer to the source for API details.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/bmpstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: BMPString
+
+.. |encoding| replace:: utf-16-be
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.BMPString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-16 big endian.
+       
+   .. automethod:: pyasn1.type.char.BMPString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.BMPString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/contents.rst
@@ -0,0 +1,20 @@
+
+Character types
+---------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/char/numericstring
+   /docs/type/char/printablestring
+   /docs/type/char/teletexstring
+   /docs/type/char/t61string
+   /docs/type/char/videotexstring
+   /docs/type/char/ia5string
+   /docs/type/char/graphicstring
+   /docs/type/char/visiblestring
+   /docs/type/char/iso646string
+   /docs/type/char/generalstring
+   /docs/type/char/universalstring
+   /docs/type/char/bmpstring
+   /docs/type/char/utf8string
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/generalstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: GeneralString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.GeneralString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a character string similar to :py:class:`GraphicString` but additionally
+       including control characters.
+
+   .. automethod:: pyasn1.type.char.GeneralString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.GeneralString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/graphicstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: GraphicString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.GraphicString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a character string that can hold any "graphical" characters
+       mixed with control ones to select particular alphabet.
+
+   .. automethod:: pyasn1.type.char.GraphicString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.GraphicString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/ia5string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: IA5String
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.IA5String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a basic character string first published in 1963 as an ISO/ITU standard, then it turned into ASCII.
+
+   .. automethod:: pyasn1.type.char.IA5String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.IA5String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/iso646string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: ISO646String
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.ISO646String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type is an alias to the :py:class:`VisibleString` type
+       
+   .. automethod:: pyasn1.type.char.ISO646String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.ISO646String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/numericstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: NumericString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.NumericString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| models character string that can be entered from a telephone handset.
+
+   .. automethod:: pyasn1.type.char.NumericString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.NumericString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/printablestring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: PrintableString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.PrintableString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| models character string that can be entered from a very rudimentary terminals featuring letters,
+       digits and punctuation marks.
+
+   .. automethod:: pyasn1.type.char.PrintableString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.PrintableString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/t61string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: T61String
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.T61String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type is an alias to :py:class:`TeletexString` type.
+
+   .. automethod:: pyasn1.type.char.T61String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.T61String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/teletexstring.rst
@@ -0,0 +1,19 @@
+
+.. |ASN.1| replace:: TeletexString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.TeletexString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models character string that can be entered from a sophisticated text processing machines
+       (by 20-th century standards) featuring letters from multiple alphabets (308 characters!), digits,
+       punctuation marks and escape sequences.
+
+   .. automethod:: pyasn1.type.char.TeletexString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.TeletexString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/universalstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: UniversalString
+
+.. |encoding| replace:: utf-32-be
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.UniversalString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-32 big endian.
+
+   .. automethod:: pyasn1.type.char.UniversalString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.UniversalString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/utf8string.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: UTF8String
+
+.. |encoding| replace:: utf-8
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.UTF8String(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a Unicode (ISO10646-1) character string implicitly serialized into UTF-8.
+       
+   .. automethod:: pyasn1.type.char.UTF8String.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.UTF8String.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/videotexstring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: VideotexString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.VideotexString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models character string that can be consumed by sophisticated video
+       terminals (by 20-th century standards) to render ascii-art style pictures and animations.
+
+   .. automethod:: pyasn1.type.char.VideotexString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.VideotexString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/char/visiblestring.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: VisibleString
+
+.. |encoding| replace:: us-ascii
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.char.VisibleString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap
+
+   .. note::
+
+       The |ASN.1| type models a character string that can hold any "graphical" characters
+       mixed with control ones to select particular alphabet.
+       
+   .. automethod:: pyasn1.type.char.VisibleString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.char.VisibleString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/contents.rst
@@ -0,0 +1,11 @@
+
+Fields of constructed types
+---------------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/namedtype/namedtype
+   /docs/type/namedtype/optionalnamedtype
+   /docs/type/namedtype/defaultednamedtype
+   /docs/type/namedtype/namedtypes
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/defaultednamedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: DefaultedNamedType
+
+|NamedType|
+------------------
+
+.. autoclass:: pyasn1.type.namedtype.DefaultedNamedType
+   :members:
+
+   .. note::
+
+        The |NamedType| class models named field of a constructed ASN.1 type which has a default value.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: NamedType
+
+|NamedType|
+-----------
+
+.. autoclass:: pyasn1.type.namedtype.NamedType
+   :members:
+
+   .. note::
+
+        The |NamedType| class models a mandatory field of a constructed ASN.1 type.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/namedtypes.rst
@@ -0,0 +1,6 @@
+
+NamedTypes
+----------
+
+.. autoclass:: pyasn1.type.namedtype.NamedTypes
+   :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedtype/optionalnamedtype.rst
@@ -0,0 +1,12 @@
+
+.. |NamedType| replace:: OptionalNamedType
+
+|NamedType|
+------------------
+
+.. autoclass:: pyasn1.type.namedtype.OptionalNamedType
+   :members:
+
+   .. note::
+
+        The |NamedType| class models an optional field of a constructed ASN.1 type.
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedval/contents.rst
@@ -0,0 +1,13 @@
+
+Enumerating numbers
+-------------------
+
+Some ASN.1 types such as :py:class:`~pyasn1.type.univ.Integer`,
+:py:class:`~pyasn1.type.univ.Enumerated` and
+:py:class:`~pyasn1.type.univ.BitString` may enumerate their values
+with human-friendly labels.
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/namedval/namedval
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/namedval/namedval.rst
@@ -0,0 +1,11 @@
+
+.. |NamedValues| replace:: NamedValues
+
+|NamedValues|
+-------------
+
+The |NamedValues| class associates human-friendly names to a set of numbers
+or bits.
+
+.. autoclass:: pyasn1.type.namedval.NamedValues
+   :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/contents.rst
@@ -0,0 +1,10 @@
+
+Tagging types
+-------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/tag/tag
+   /docs/type/tag/tagset
+   /docs/type/tag/tagmap
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tag.rst
@@ -0,0 +1,8 @@
+
+Solitary tag
+------------
+
+.. automodule:: pyasn1.type.tag
+   :members: Tag, tagClassUniversal, tagClassApplication, tagClassContext,
+             tagClassPrivate, tagFormatSimple, tagFormatConstructed
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tagmap.rst
@@ -0,0 +1,6 @@
+
+Tag->type map
+-------------
+
+.. autoclass:: pyasn1.type.tagmap.TagMap
+   :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/tag/tagset.rst
@@ -0,0 +1,6 @@
+
+Composition of tags
+-------------------
+
+.. autoclass:: pyasn1.type.tag.TagSet
+   :members:
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/any.rst
@@ -0,0 +1,20 @@
+
+.. |ASN.1| replace:: Any
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Any(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1', binValue=NoValue(),hexValue=NoValue())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+   .. note::
+
+       The |ASN.1| type models an arbitrary value of an arbitrary type. Sometimes
+       type is defined by accompanying object identifier or an integer identifier.
+       Frequently ANY value holds a serialized representation of some other ASN.1
+       object.
+
+   .. automethod:: pyasn1.type.univ.Any.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1')
+   .. automethod:: pyasn1.type.univ.Any.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(),encoding='iso-8859-1')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/bitstring.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: BitString
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.BitString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, asInteger, asNumbers, asOctets, asBinary, fromHexString, fromBinaryString, fromOctetString
+
+   .. note::
+
+        The |ASN.1| type models an arbitrary sequence of bits.
+
+   .. automethod:: pyasn1.type.univ.BitString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
+   .. automethod:: pyasn1.type.univ.BitString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), , namedValues=NamedValues(),binValue=NoValue(), hexValue=NoValue())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/boolean.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Boolean
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Boolean(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+   .. note::
+
+       The |ASN.1| type models a BOOLEAN that can be either TRUE or FALSE.
+
+   .. automethod:: pyasn1.type.univ.Boolean.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.Boolean.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/choice.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Choice
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Choice(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+             getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
+             getComponentByType, setComponentByType, getName, getComponent
+
+   .. note::
+
+        The |ASN.1| type can only hold a single component at a time belonging to the list of allowed types.
+
+   .. automethod:: pyasn1.type.univ.Choice.clone(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.Choice.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/contents.rst
@@ -0,0 +1,23 @@
+
+Universal types
+---------------
+
+.. autoclass:: pyasn1.type.univ.NoValue()
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/univ/integer
+   /docs/type/univ/boolean
+   /docs/type/univ/bitstring
+   /docs/type/univ/octetstring
+   /docs/type/univ/null
+   /docs/type/univ/objectidentifier
+   /docs/type/univ/real
+   /docs/type/univ/enumerated
+   /docs/type/univ/any
+   /docs/type/univ/setof
+   /docs/type/univ/sequenceof
+   /docs/type/univ/set
+   /docs/type/univ/sequence
+   /docs/type/univ/choice
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/enumerated.rst
@@ -0,0 +1,16 @@
+
+.. |ASN.1| replace:: Enumerated
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Enumerated(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, namedValues
+
+   .. note::
+
+        The |ASN.1| type models bounded set of named integer values. Other than that, it is identical to
+        the *Integer* class.
+
+   .. automethod:: pyasn1.type.univ.Enumerated.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+   .. automethod:: pyasn1.type.univ.Enumerated.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/integer.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Integer
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Integer(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap,
+             subtypeSpec, namedValues
+
+   .. note::
+
+        The |ASN.1| type models an arbitrary integer. INTEGER values can be positive, negative,
+        or zero, and can have any magnitude.
+       
+   .. automethod:: pyasn1.type.univ.Integer.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
+   .. automethod:: pyasn1.type.univ.Integer.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(), namedValues=NamedValues())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/null.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Null
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Null(value=NoValue(), tagSet=TagSet())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec
+
+   .. note::
+
+       The |ASN.1| type models ASN.1 NULL.
+
+   .. automethod:: pyasn1.type.univ.Null.clone(value=NoValue(), tagSet=TagSet())
+   .. automethod:: pyasn1.type.univ.Null.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/objectidentifier.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: ObjectIdentifier
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.ObjectIdentifier(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, isPrefixOf
+
+   .. note::
+
+        The |ASN.1| type models ASN.1 OBJECT IDENTIFIER as a sequence of integer numbers.
+
+   .. automethod:: pyasn1.type.univ.ObjectIdentifier.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.ObjectIdentifier.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/octetstring.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: OctetString
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.OctetString(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1', binValue=NoValue(),hexValue=NoValue())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, fromHexString, fromBinaryString
+
+   .. note::
+
+        The |ASN.1| type models an arbitrary string of octets (eight-bit numbers), not printable text string.
+
+   .. automethod:: pyasn1.type.univ.OctetString.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='iso-8859-1')
+   .. automethod:: pyasn1.type.univ.OctetString.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection(),encoding='iso-8859-1')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/real.rst
@@ -0,0 +1,15 @@
+
+.. |ASN.1| replace:: Real
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Real(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, subtypeSpec, isInf, isPlusInf, isMinusInf
+
+   .. note::
+
+       The |ASN.1| type models a rational number of arbitrary precision.
+
+   .. automethod:: pyasn1.type.univ.Real.clone(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.Real.subtype(value=NoValue(), implicitTag=Tag(), explicitTag=Tag(), subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/sequence.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: Sequence
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Sequence(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec, getComponentByPosition,
+             setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents
+
+   .. note::
+
+        The |ASN.1| type models a collection of named ASN.1 components.
+        Ordering of the components **is** preserved upon de/serialization.
+
+   .. automethod:: pyasn1.type.univ.Sequence.clone(componentType=None, tagSet=tagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.Sequence.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/sequenceof.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: SequenceOf
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.SequenceOf(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+             getComponentByPosition, setComponentByPosition
+
+   .. note::
+
+       The |ASN.1| type models a collection of elements of a single ASN.1 type.
+       Ordering of the components **is** preserved upon de/serialization.
+        
+   .. automethod:: pyasn1.type.univ.SequenceOf.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.SequenceOf.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/set.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: Set
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.Set(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+             getComponentByPosition, setComponentByPosition, getComponentByName, setComponentByName, setDefaultComponents,
+             getComponentByType, setComponentByType
+
+   .. note::
+
+        The |ASN.1| type models a collection of named ASN.1 components.
+        Ordering of the components **is not** preserved upon de/serialization.
+
+   .. automethod:: pyasn1.type.univ.Set.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.Set.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/univ/setof.rst
@@ -0,0 +1,17 @@
+
+.. |ASN.1| replace:: SetOf
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.univ.SetOf(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), sizeSpec=ConstraintsIntersection())
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, effectiveTagSet, tagMap, componentType, subtypeSpec, sizeSpec,
+             getComponentByPosition, setComponentByPosition
+
+   .. note::
+
+        The |ASN.1| type models a collection of elements of a single ASN.1 type.
+        Ordering of the components **is not** preserved upon de/serialization.
+
+   .. automethod:: pyasn1.type.univ.SetOf.clone(componentType=None, tagSet=TagSet(), subtypeSpec=ConstraintsIntersection())
+   .. automethod:: pyasn1.type.univ.SetOf.subtype(componentType=None, implicitTag=Tag(), explicitTag=Tag(),subtypeSpec=ConstraintsIntersection())
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/contents.rst
@@ -0,0 +1,10 @@
+
+Useful types
+------------
+
+.. toctree::
+   :maxdepth: 2
+
+   /docs/type/useful/objectdescriptor
+   /docs/type/useful/generalizedtime
+   /docs/type/useful/utctime
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/generalizedtime.rst
@@ -0,0 +1,35 @@
+
+.. |ASN.1| replace:: GeneralizedTime
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.GeneralizedTime(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, asDateTime, fromDateTime
+
+   .. note::
+
+
+       The |ASN.1| type models a character string representing date and time
+       in many different formats.
+
+       Formal syntax for the *GeneralizedTime* value is:
+
+       * **YYYYMMDDhh[mm[ss[(.|,)ffff]]]** standing for a local time, four
+         digits for the year, two for the month, two for the day and two
+         for the hour, followed by two digits for the minutes and two
+         for the seconds if required, then a dot (or a comma), and a
+         number for the fractions of second or
+
+       * a string as above followed by the letter “Z” (denoting a UTC
+         time) or
+
+       * a string as above followed by a string **(+|-)hh[mm]** denoting
+         time zone offset relative to UTC
+
+       For example, *20170126120000Z* stands for YYYYMMDDHHMMSSZ.
+
+   .. automethod:: pyasn1.type.useful.GeneralizedTime.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.useful.GeneralizedTime.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/objectdescriptor.rst
@@ -0,0 +1,18 @@
+
+.. |ASN.1| replace:: ObjectDescriptor
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.ObjectDescriptor(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet
+
+   .. note::
+
+       The |ASN.1| type models a character string that can accompany the *ObjectIdentifier* type
+       to serve as a human-friendly annotation for an OBJECT IDENTIFIER.
+
+   .. automethod:: pyasn1.type.useful.ObjectDescriptor.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.useful.ObjectDescriptor.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/docs/type/useful/utctime.rst
@@ -0,0 +1,32 @@
+
+.. |ASN.1| replace:: UTCTime
+
+.. |encoding| replace:: iso-8859-1
+
+|ASN.1| type
+------------
+
+.. autoclass:: pyasn1.type.useful.UTCTime(value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   :members: isValue, isSameTypeWith, isSuperTypeOf, tagSet, asDateTime, fromDateTime
+
+   .. note::
+
+       The |ASN.1| type models a character string representing date and time.
+
+       Formal syntax for the *UTCTime* value is:
+
+       * **YYMMDDhhmm[ss]** standing for UTC time, two
+         digits for the year, two for the month, two for the day and two
+         for the hour, followed by two digits for the minutes and two
+         for the seconds if required or
+
+       * a string as above followed by the letter “Z” (denoting a UTC
+         time) or
+
+       * a string as above followed by a string **(+|-)hhmm** denoting
+         time zone offset relative to UTC
+
+       For example, *170126120000Z* which stands for YYMMDDHHMMSSZ.
+
+   .. automethod:: pyasn1.type.useful.UTCTime.clone(self, value=NoValue(), tagSet=TagSet(), subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
+   .. automethod:: pyasn1.type.useful.UTCTime.subtype(self, value=NoValue(), implicitTag=TagSet(), explicitTag=TagSet(),subtypeSpec=ConstraintsIntersection(), encoding='us-ascii')
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/example-use-case.rst
@@ -0,0 +1,193 @@
+
+Example use case
+================
+
+.. toctree::
+   :maxdepth: 2
+
+To briefly explain how to approach pyasn1, consider a quick workflow example.
+
+Grab ASN.1 schema for SSH keys
+------------------------------
+
+ASN.1 is widely used in many Internet protocols. Frequently, whenever ASN.1 is employed,
+data structures are described in ASN.1 schema language right in the RFC.
+Take `RFC2437 <https://www.ietf.org/rfc/rfc2437.txt>`_ for example -- we can look into
+it and weed out data structures specification into a local file:
+
+.. code-block:: python
+
+    # pkcs-1.asn
+
+    PKCS-1 {iso(1) member(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) modules(0) pkcs-1(1)}
+
+    DEFINITIONS EXPLICIT TAGS ::= BEGIN
+        RSAPrivateKey ::= SEQUENCE {
+             version Version,
+             modulus INTEGER,
+             publicExponent INTEGER,
+             privateExponent INTEGER,
+             prime1 INTEGER,
+             prime2 INTEGER,
+             exponent1 INTEGER,
+             exponent2 INTEGER,
+             coefficient INTEGER
+        }
+        Version ::= INTEGER
+    END
+
+Compile ASN.1 schema into Python
+--------------------------------
+
+In the best case, you should be able to automatically compile ASN.1 spec into
+Python classes. For that purpose we have the `asn1ate <https://github.com/kimgr/asn1ate>`_
+tool:
+
+.. code-block:: bash
+
+    $ pyasn1gen.py pkcs-1.asn > rsakey.py
+
+Though it may not work out as, as it stands now, asn1ate does not support
+all ASN.1 language constructs.
+
+Alternatively, you could check out the `pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_
+package to see if it already has the ASN.1 spec you are looking for compiled and shipped
+there. Then just install the package, import the data structure you need and use it:
+
+.. code-block:: bash
+
+    $ pip install pyasn1-modules
+
+As a last resort, you could express ASN.1 in Python by hand. The end result
+should be a declarative Python code resembling original ASN.1 syntax like
+this:
+
+.. code-block:: python
+
+    # rsakey.py
+
+    class Version(Integer):
+        pass
+
+    class RSAPrivateKey(Sequence):
+        componentType = NamedTypes(
+            NamedType('version', Version()),
+            NamedType('modulus', Integer()),
+            NamedType('publicExponent', Integer()),
+            NamedType('privateExponent', Integer()),
+            NamedType('prime1', Integer()),
+            NamedType('prime2', Integer()),
+            NamedType('exponent1', Integer()),
+            NamedType('exponent2', Integer()),
+            NamedType('coefficient', Integer())
+        )
+
+Read your ~/.ssh/id_rsa
+-----------------------
+
+Given we've put our Python classes into the `rsakey.py` module, we could import
+the top-level object for SSH keys container and initialize it from our
+`~/.ssh/id_rsa` file (for sake of simplicity here we assume no passphrase is
+set on the key file):
+
+.. code-block:: python
+
+    from base64 import b64decode
+    from pyasn1.codec.der.decoder import decode as der_decoder
+    from rsakey import RSAPrivateKey
+
+    # Read SSH key from file (assuming no passphrase)
+    with open open('.ssh/id_rsa') as key_file:
+        b64_serialization = ''.join(key_file.readlines()[1:-1])
+
+    # Undo BASE64 serialization
+    der_serialization = b64decode(b64_serialization)
+
+    # Undo DER serialization, reconstruct SSH key structure
+    private_key, rest_of_input = der_decoder(der_serialization, asn1Spec=RSAPrivateKey())
+
+Once we have Python ASN.1 structures initialized, we could inspect them:
+
+.. code-block:: pycon
+
+    >>> print(private_key.prettyPrint())
+    RSAPrivateKey:
+     version=0
+     modulus=280789907761334970323210643584308373...
+     publicExponent=65537
+     privateExponent=1704567874679144879123080924...
+     prime1=1780178536719561265324798296279384073...
+     prime2=1577313184995269616049017780493740138...
+     exponent1=1193974819720845247396384239609024...
+     exponent2=9240965721817961178848297404494811...
+     coefficient=10207364473358910343346707141115...
+
+Play with the keys
+------------------
+
+As well as use them nearly as we do with native Python types:
+
+.. code-block:: pycon
+
+    >>> pk = private_key
+    >>>
+    >>> pk['prime1'] * pk['prime2'] == pk['modulus']
+    True
+    >>> pk['prime1'] == pk['modulus'] // pk['prime2']
+    True
+    >>> pk['exponent1'] == pk['privateExponent'] % (pk['prime1'] - 1)
+    True
+    >>> pk['exponent2'] == pk['privateExponent'] % (pk['prime2'] - 1)
+    True
+
+Technically, pyasn1 classes `emulate <https://docs.python.org/3/reference/datamodel.html#emulating-container-types>`_
+Python built-in types.
+
+Transform to built-ins
+----------------------
+
+ASN.1 data structures exhibit a way more complicated behaviour compared to
+Python types. You may wish to simplify things by turning the whole tree of
+pyasn1 objects into an analogous tree made of base Python types:
+
+.. code-block:: pycon
+
+    >>> from pyasn1.codec.native.encoder import encode
+    >>> ...
+    >>> py_private_key = encode(private_key)
+    >>> py_private_key
+    {'version': 0, 'modulus': 280789907761334970323210643584308373, 'publicExponent': 65537,
+     'privateExponent': 1704567874679144879123080924, 'prime1': 1780178536719561265324798296279384073,
+     'prime2': 1577313184995269616049017780493740138, 'exponent1': 1193974819720845247396384239609024,
+     'exponent2': 9240965721817961178848297404494811, 'coefficient': 10207364473358910343346707141115}
+
+You can do vice-versa: initialize ASN.1 structure from a dict:
+
+.. code-block:: pycon
+
+    >>> from pyasn1.codec.native.decoder import decode
+    >>> py_private_key = {'modulus': 280789907761334970323210643584308373}
+    >>> private_key = decode(py_private_key, asn1Spec=RSAPrivateKey())
+
+Write it back
+-------------
+
+Possibly not that applicable to the SSH key example, but you can of course modify
+any part of the ASN.1 data structure and serialize it back into the same or other
+wire representation:
+
+.. code-block:: python
+
+    from pyasn1.codec.der.encoder import encode as der_encoder
+
+    # Serialize SSH key data structure into DER stream
+    der_serialization = der_encoder(private_key)
+
+    # Serialize DER stream into BASE64 stream
+    b64_serialization = '-----BEGIN RSA PRIVATE KEY-----\n'
+    b64_serialization += b64encode(der_serialization)
+    b64_serialization += '-----END RSA PRIVATE KEY-----\n'
+
+    with open('.ssh/id_rsa.new', 'w') as key_file:
+        key_file.write(b64_serialization)
+
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/doc/source/license.rst
@@ -0,0 +1,6 @@
+.. _license:
+
+License
+=======
+
+.. include:: ../../LICENSE.rst
deleted file mode 100644
--- a/third_party/python/pyasn1/doc/tagging.html
+++ /dev/null
@@ -1,233 +0,0 @@
-<html>
-<title>
-Tagging in PyASN1
-</title>
-<head>
-</head>
-<body>
-<center>
-<table width=60%>
-<tr>
-<td>
-<a name="1.2"></a>
-<h4>
-1.2 Tagging in PyASN1
-</h4>
-
-<p>
-In order to continue with the Constructed ASN.1 types, we will first have
-to introduce the concept of tagging (and its pyasn1 implementation), as
-some of the Constructed types rely upon the tagging feature.
-</p>
-
-<p>
-When a value is coming into an ASN.1-based system (received from a network
-or read from some storage), the receiving entity has to determine the
-type of the value to interpret and verify it accordingly.
-</p>
-
-<p>
-Historically, the first data serialization protocol introduced in
-ASN.1 was BER (Basic Encoding Rules). According to BER, any serialized
-value is packed into a triplet of (Type, Length, Value) where Type is a 
-code that identifies the value (which is called <i>tag</i> in ASN.1),
-length is the number of bytes occupied by the value in its serialized form
-and value is ASN.1 value in a form suitable for serial transmission or storage.
-</p>
-
-<p>
-For that reason almost every ASN.1 type has a tag (which is actually a
-BER type) associated with it by default.
-</p>
-
-<p>
-An ASN.1 tag could be viewed as a tuple of three numbers:
-(Class, Format, Number). While Number identifies a tag, Class component 
-is used to create scopes for Numbers. Four scopes are currently defined:
-UNIVERSAL, context-specific, APPLICATION and PRIVATE. The Format component
-is actually a one-bit flag - zero for tags associated with scalar types,
-and one for constructed types (will be discussed later on).
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] INTEGER
-MyOctetString ::= [APPLICATION 0] OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-In pyasn1, tags are implemented as immutable, tuple-like objects:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> myTag = tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
->>> myTag
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tuple(myTag)
-(128, 0, 10)
->>> myTag[2]
-10
->>> myTag == tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)
-False
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Default tag, associated with any ASN.1 type, could be extended or replaced
-to make new type distinguishable from its ancestor. The standard provides
-two modes of tag mangling - IMPLICIT and EXPLICIT.
-</p>
-
-<p>
-EXPLICIT mode works by appending new tag to the existing ones thus creating
-an ordered set of tags. This set will be considered as a whole for type
-identification and encoding purposes. Important property of EXPLICIT tagging
-mode is that it preserves base type information in encoding what makes it
-possible to completely recover type information from encoding.
-</p>
-
-<p>
-When tagging in IMPLICIT mode, the outermost existing tag is dropped and
-replaced with a new one.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] IMPLICIT INTEGER
-MyOctetString ::= [APPLICATION 0] EXPLICIT OCTET STRING
-</pre>
-</td></tr></table>
-
-<p>
-To model both modes of tagging, a specialized container TagSet object (holding
-zero, one or more Tag objects) is used in pyasn1.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet = tag.TagSet(
-...   # base tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10),
-...   # effective tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10))
->>> tagSet.getBaseTag()
-Tag(tagClass=128, tagFormat=0, tagId=10)
->>> tagSet = tagSet.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
-       Tag(tagClass=128, tagFormat=32, tagId=20))
->>> tagSet = tagSet.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 30)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10), 
-       Tag(tagClass=128, tagFormat=32, tagId=20), 
-       Tag(tagClass=128, tagFormat=32, tagId=30))
->>> tagSet = tagSet.tagImplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 40)
-... )
->>> tagSet
-TagSet(Tag(tagClass=128, tagFormat=0, tagId=10),
-       Tag(tagClass=128, tagFormat=32, tagId=20),
-       Tag(tagClass=128, tagFormat=32, tagId=40))
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-As a side note: the "base tag" concept (accessible through the getBaseTag()
-method) is specific to pyasn1 -- the base tag is used to identify the original
-ASN.1 type of an object in question. Base tag is never occurs in encoding
-and is mostly used internally by pyasn1 for choosing type-specific data 
-processing algorithms. The "effective tag" is the one that always appears in
-encoding and is used on tagSets comparation.
-</p>
-
-<p>
-Any two TagSet objects could be compared to see if one is a derivative
-of the other. Figuring this out is also useful in cases when a type-specific
-data processing algorithms are to be chosen.
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import tag
->>> tagSet1 = tag.TagSet(
-...   # base tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-...   # effective tag
-...   tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)
-... )
->>> tagSet2 = tagSet1.tagExplicitly(
-...    tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 20)
-... )
->>> tagSet1.isSuperTagSetOf(tagSet2)
-True
->>> tagSet2.isSuperTagSetOf(tagSet1)
-False
->>> 
-</pre>
-</td></tr></table>
-
-<p>
-We will complete this discussion on tagging with a real-world example. The
-following ASN.1 tagged type:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
-MyIntegerType ::= [12] EXPLICIT INTEGER
-</pre>
-</td></tr></table>
-
-<p>
-could be expressed in pyasn1 like this:
-</p>
-
-<table bgcolor="lightgray" border=0 width=100%><TR><TD>
-<pre>
->>> from pyasn1.type import univ, tag
->>> class MyIntegerType(univ.Integer):
-...   tagSet = univ.Integer.tagSet.tagExplicitly(
-...        tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 12)
-...        )
->>> myInteger = MyIntegerType(12345)
->>> myInteger.getTagSet()
-TagSet(Tag(tagClass=0, tagFormat=0, tagId=2), 
-       Tag(tagClass=128, tagFormat=32, tagId=12))
->>>
-</pre>
-</td></tr></table>
-
-<p>
-Referring to the above code, the tagSet class attribute is a property of any
-pyasn1 type object that assigns default tagSet to a pyasn1 value object. This
-default tagSet specification can be ignored and effectively replaced by some
-other tagSet value passed on object instantiation.
-</p>
-
-<p>
-It's important to understand that the tag set property of pyasn1 type/value
-object can never be modifed in place. In other words, a pyasn1 type/value
-object can never change its tags. The only way is to create a new pyasn1
-type/value object and associate different tag set with it.
-</p>
-
-<hr>
-
-</td>
-</tr>
-</table>
-</center>
-</body>
-</html>
--- a/third_party/python/pyasn1/pyasn1.egg-info/PKG-INFO
+++ b/third_party/python/pyasn1/pyasn1.egg-info/PKG-INFO
@@ -1,26 +1,33 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: pyasn1
-Version: 0.1.7
+Version: 0.3.7
 Summary: ASN.1 types and codecs
-Home-page: http://sourceforge.net/projects/pyasn1/
-Author: Ilya Etingof <ilya@glas.net>
-Author-email: ilya@glas.net
+Home-page: https://github.com/etingof/pyasn1
+Author: Ilya Etingof <etingof@gmail.com>
+Author-email: etingof@gmail.com
 License: BSD
-Description: A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
+Description: Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Education
 Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: Science/Research
 Classifier: Intended Audience :: System Administrators
 Classifier: Intended Audience :: Telecommunications Industry
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Communications
-Classifier: Topic :: Security :: Cryptography
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
--- a/third_party/python/pyasn1/pyasn1.egg-info/SOURCES.txt
+++ b/third_party/python/pyasn1/pyasn1.egg-info/SOURCES.txt
@@ -1,22 +1,71 @@
-CHANGES
-LICENSE
+CHANGES.rst
+LICENSE.rst
 MANIFEST.in
-README
-THANKS
-TODO
+README.md
+TODO.rst
+setup.cfg
 setup.py
-doc/codecs.html
-doc/constraints.html
-doc/constructed.html
-doc/intro.html
-doc/pyasn1-tutorial.html
-doc/scalar.html
-doc/tagging.html
+doc/Makefile
+doc/source/changelog.rst
+doc/source/conf.py
+doc/source/contents.rst
+doc/source/example-use-case.rst
+doc/source/license.rst
+doc/source/docs/api-reference.rst
+doc/source/docs/tutorial.rst
+doc/source/docs/codec/ber/contents.rst
+doc/source/docs/codec/cer/contents.rst
+doc/source/docs/codec/der/contents.rst
+doc/source/docs/codec/native/contents.rst
+doc/source/docs/type/char/bmpstring.rst
+doc/source/docs/type/char/contents.rst
+doc/source/docs/type/char/generalstring.rst
+doc/source/docs/type/char/graphicstring.rst
+doc/source/docs/type/char/ia5string.rst
+doc/source/docs/type/char/iso646string.rst
+doc/source/docs/type/char/numericstring.rst
+doc/source/docs/type/char/printablestring.rst
+doc/source/docs/type/char/t61string.rst
+doc/source/docs/type/char/teletexstring.rst
+doc/source/docs/type/char/universalstring.rst
+doc/source/docs/type/char/utf8string.rst
+doc/source/docs/type/char/videotexstring.rst
+doc/source/docs/type/char/visiblestring.rst
+doc/source/docs/type/namedtype/contents.rst
+doc/source/docs/type/namedtype/defaultednamedtype.rst
+doc/source/docs/type/namedtype/namedtype.rst
+doc/source/docs/type/namedtype/namedtypes.rst
+doc/source/docs/type/namedtype/optionalnamedtype.rst
+doc/source/docs/type/namedval/contents.rst
+doc/source/docs/type/namedval/namedval.rst
+doc/source/docs/type/tag/contents.rst
+doc/source/docs/type/tag/tag.rst
+doc/source/docs/type/tag/tagmap.rst
+doc/source/docs/type/tag/tagset.rst
+doc/source/docs/type/univ/any.rst
+doc/source/docs/type/univ/bitstring.rst
+doc/source/docs/type/univ/boolean.rst
+doc/source/docs/type/univ/choice.rst
+doc/source/docs/type/univ/contents.rst
+doc/source/docs/type/univ/enumerated.rst
+doc/source/docs/type/univ/integer.rst
+doc/source/docs/type/univ/null.rst
+doc/source/docs/type/univ/objectidentifier.rst
+doc/source/docs/type/univ/octetstring.rst
+doc/source/docs/type/univ/real.rst
+doc/source/docs/type/univ/sequence.rst
+doc/source/docs/type/univ/sequenceof.rst
+doc/source/docs/type/univ/set.rst
+doc/source/docs/type/univ/setof.rst
+doc/source/docs/type/useful/contents.rst
+doc/source/docs/type/useful/generalizedtime.rst
+doc/source/docs/type/useful/objectdescriptor.rst
+doc/source/docs/type/useful/utctime.rst
 pyasn1/__init__.py
 pyasn1/debug.py
 pyasn1/error.py
 pyasn1.egg-info/PKG-INFO
 pyasn1.egg-info/SOURCES.txt
 pyasn1.egg-info/dependency_links.txt
 pyasn1.egg-info/top_level.txt
 pyasn1.egg-info/zip-safe
@@ -26,43 +75,65 @@ pyasn1/codec/ber/decoder.py
 pyasn1/codec/ber/encoder.py
 pyasn1/codec/ber/eoo.py
 pyasn1/codec/cer/__init__.py
 pyasn1/codec/cer/decoder.py
 pyasn1/codec/cer/encoder.py
 pyasn1/codec/der/__init__.py
 pyasn1/codec/der/decoder.py
 pyasn1/codec/der/encoder.py
+pyasn1/codec/native/__init__.py
+pyasn1/codec/native/decoder.py
+pyasn1/codec/native/encoder.py
 pyasn1/compat/__init__.py
+pyasn1/compat/binary.py
+pyasn1/compat/calling.py
+pyasn1/compat/dateandtime.py
+pyasn1/compat/integer.py
 pyasn1/compat/octets.py
+pyasn1/compat/string.py
 pyasn1/type/__init__.py
 pyasn1/type/base.py
 pyasn1/type/char.py
 pyasn1/type/constraint.py
 pyasn1/type/error.py
 pyasn1/type/namedtype.py
 pyasn1/type/namedval.py
 pyasn1/type/tag.py
 pyasn1/type/tagmap.py
 pyasn1/type/univ.py
 pyasn1/type/useful.py
-test/__init__.py
-test/suite.py
-test/codec/__init__.py
-test/codec/suite.py
-test/codec/ber/__init__.py
-test/codec/ber/suite.py
-test/codec/ber/test_decoder.py
-test/codec/ber/test_encoder.py
-test/codec/cer/__init__.py
-test/codec/cer/suite.py
-test/codec/cer/test_decoder.py
-test/codec/cer/test_encoder.py
-test/codec/der/__init__.py
-test/codec/der/suite.py
-test/codec/der/test_decoder.py
-test/codec/der/test_encoder.py
-test/type/__init__.py
-test/type/suite.py
-test/type/test_constraint.py
-test/type/test_namedtype.py
-test/type/test_tag.py
-test/type/test_univ.py
\ No newline at end of file
+tests/__init__.py
+tests/__main__.py
+tests/base.py
+tests/test_debug.py
+tests/codec/__init__.py
+tests/codec/__main__.py
+tests/codec/ber/__init__.py
+tests/codec/ber/__main__.py
+tests/codec/ber/test_decoder.py
+tests/codec/ber/test_encoder.py
+tests/codec/cer/__init__.py
+tests/codec/cer/__main__.py
+tests/codec/cer/test_decoder.py
+tests/codec/cer/test_encoder.py
+tests/codec/der/__init__.py
+tests/codec/der/__main__.py
+tests/codec/der/test_decoder.py
+tests/codec/der/test_encoder.py
+tests/codec/native/__init__.py
+tests/codec/native/__main__.py
+tests/codec/native/test_decoder.py
+tests/codec/native/test_encoder.py
+tests/compat/__init__.py
+tests/compat/__main__.py
+tests/compat/test_binary.py
+tests/compat/test_integer.py
+tests/compat/test_octets.py
+tests/type/__init__.py
+tests/type/__main__.py
+tests/type/test_char.py
+tests/type/test_constraint.py
+tests/type/test_namedtype.py
+tests/type/test_namedval.py
+tests/type/test_tag.py
+tests/type/test_univ.py
+tests/type/test_useful.py
\ No newline at end of file
--- a/third_party/python/pyasn1/pyasn1/__init__.py
+++ b/third_party/python/pyasn1/pyasn1/__init__.py
@@ -1,8 +1,7 @@
 import sys
 
 # http://www.python.org/dev/peps/pep-0396/
-__version__ = '0.1.7'
+__version__ = '0.3.7'
 
 if sys.version_info[:2] < (2, 4):
-  raise RuntimeError('PyASN1 requires Python 2.4 or later')
-
+    raise RuntimeError('PyASN1 requires Python 2.4 or later')
--- a/third_party/python/pyasn1/pyasn1/codec/ber/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/decoder.py
@@ -1,683 +1,1061 @@
-# BER decoder
-from pyasn1.type import tag, base, univ, char, useful, tagmap
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import base, tag, univ, char, useful, tagmap
 from pyasn1.codec.ber import eoo
-from pyasn1.compat.octets import oct2int, octs2ints, isOctetsType
+from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null
+from pyasn1.compat.integer import from_bytes
 from pyasn1 import debug, error
 
-class AbstractDecoder:
+__all__ = ['decode']
+
+noValue = base.noValue
+
+
+class AbstractDecoder(object):
     protoComponent = None
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
         raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
 
+
 class AbstractSimpleDecoder(AbstractDecoder):
-    tagFormats = (tag.tagFormatSimple,)
-    def _createComponent(self, asn1Spec, tagSet, value=None):
-        if tagSet[0][1] not in self.tagFormats:
-            raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
+    @staticmethod
+    def substrateCollector(asn1Object, substrate, length):
+        return substrate[:length], substrate[length:]
+
+    def _createComponent(self, asn1Spec, tagSet, value=noValue):
         if asn1Spec is None:
-            return self.protoComponent.clone(value, tagSet)
-        elif value is None:
+            return self.protoComponent.clone(value, tagSet=tagSet)
+        elif value is noValue:
             return asn1Spec
         else:
             return asn1Spec.clone(value)
-        
-class AbstractConstructedDecoder(AbstractDecoder):
-    tagFormats = (tag.tagFormatConstructed,)
-    def _createComponent(self, asn1Spec, tagSet, value=None):
-        if tagSet[0][1] not in self.tagFormats:
-            raise error.PyAsn1Error('Invalid tag format %r for %r' % (tagSet[0], self.protoComponent,))
-        if asn1Spec is None:
-            return self.protoComponent.clone(tagSet)
-        else:
-            return asn1Spec.clone()
-                                
-class EndOfOctetsDecoder(AbstractSimpleDecoder):
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
-        return eoo.endOfOctets, substrate[length:]
+
 
 class ExplicitTagDecoder(AbstractSimpleDecoder):
     protoComponent = univ.Any('')
-    tagFormats = (tag.tagFormatConstructed,)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         if substrateFun:
             return substrateFun(
-                       self._createComponent(asn1Spec, tagSet, ''),
-                       substrate, length
-                   )
+                self._createComponent(asn1Spec, tagSet, ''),
+                substrate, length
+            )
+
         head, tail = substrate[:length], substrate[length:]
-        value, _ = decodeFun(head, asn1Spec, tagSet, length)
+
+        value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)
+
         return value, tail
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
         if substrateFun:
             return substrateFun(
-                       self._createComponent(asn1Spec, tagSet, ''),
-                       substrate, length
-                   )
-        value, substrate = decodeFun(substrate, asn1Spec, tagSet, length)
-        terminator, substrate = decodeFun(substrate)
-        if eoo.endOfOctets.isSameTypeWith(terminator) and \
-                terminator == eoo.endOfOctets:
+                self._createComponent(asn1Spec, tagSet, ''),
+                substrate, length
+            )
+
+        value, substrate = decodeFun(substrate, asn1Spec, tagSet, length, **options)
+
+        eooMarker, substrate = decodeFun(substrate, allowEoo=True, **options)
+
+        if eooMarker is eoo.endOfOctets:
             return value, substrate
         else:
             raise error.PyAsn1Error('Missing end-of-octets terminator')
 
+
 explicitTagDecoder = ExplicitTagDecoder()
 
+
 class IntegerDecoder(AbstractSimpleDecoder):
     protoComponent = univ.Integer(0)
-    precomputedValues = {
-        '\x00':  0,
-        '\x01':  1,
-        '\x02':  2,
-        '\x03':  3,
-        '\x04':  4,
-        '\x05':  5,
-        '\x06':  6,
-        '\x07':  7,
-        '\x08':  8,
-        '\x09':  9,
-        '\xff': -1,
-        '\xfe': -2,
-        '\xfd': -3,
-        '\xfc': -4,
-        '\xfb': -5
-        }
-    
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
-                     state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+
+        if tagSet[0].tagFormat != tag.tagFormatSimple:
+            raise error.PyAsn1Error('Simple tag format expected')
+
         head, tail = substrate[:length], substrate[length:]
+
         if not head:
             return self._createComponent(asn1Spec, tagSet, 0), tail
-        if head in self.precomputedValues:
-            value = self.precomputedValues[head]
-        else:
-            firstOctet = oct2int(head[0])
-            if firstOctet & 0x80:
-                value = -1
-            else:
-                value = 0
-            for octet in head:
-                value = value << 8 | oct2int(octet)
+
+        value = from_bytes(head, signed=True)
+
         return self._createComponent(asn1Spec, tagSet, value), tail
 
+
 class BooleanDecoder(IntegerDecoder):
     protoComponent = univ.Boolean(0)
-    def _createComponent(self, asn1Spec, tagSet, value=None):
+
+    def _createComponent(self, asn1Spec, tagSet, value=noValue):
         return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0)
 
+
 class BitStringDecoder(AbstractSimpleDecoder):
     protoComponent = univ.BitString(())
-    tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
-                     state, decodeFun, substrateFun):
+    supportConstructedForm = True
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         head, tail = substrate[:length], substrate[length:]
-        if tagSet[0][1] == tag.tagFormatSimple:    # XXX what tag to check?
+        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?
             if not head:
                 raise error.PyAsn1Error('Empty substrate')
             trailingBits = oct2int(head[0])
             if trailingBits > 7:
                 raise error.PyAsn1Error(
                     'Trailing bits overflow %s' % trailingBits
-                    )
+                )
             head = head[1:]
-            lsb = p = 0; l = len(head)-1; b = ()
-            while p <= l:
-                if p == l:
-                    lsb = trailingBits
-                j = 7                    
-                o = oct2int(head[p])
-                while j >= lsb:
-                    b = b + ((o>>j)&0x01,)
-                    j = j - 1
-                p = p + 1
-            return self._createComponent(asn1Spec, tagSet, b), tail
-        r = self._createComponent(asn1Spec, tagSet, ())
+            value = self.protoComponent.fromOctetString(head, trailingBits)
+            return self._createComponent(asn1Spec, tagSet, value), tail
+
+        if not self.supportConstructedForm:
+            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+
+        bitString = self._createComponent(asn1Spec, tagSet)
+
         if substrateFun:
-            return substrateFun(r, substrate, length)
+            return substrateFun(bitString, substrate, length)
+
         while head:
-            component, head = decodeFun(head)
-            r = r + component
-        return r, tail
+            component, head = decodeFun(head, self.protoComponent, **options)
+            bitString += component
+
+        return bitString, tail
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
-        r = self._createComponent(asn1Spec, tagSet, '')
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
+        bitString = self._createComponent(asn1Spec, tagSet)
+
         if substrateFun:
-            return substrateFun(r, substrate, length)
+            return substrateFun(bitString, substrate, length)
+
         while substrate:
-            component, substrate = decodeFun(substrate)
-            if eoo.endOfOctets.isSameTypeWith(component) and \
-                    component == eoo.endOfOctets:
+            component, substrate = decodeFun(substrate, self.protoComponent,
+                                             allowEoo=True, **options)
+            if component is eoo.endOfOctets:
                 break
-            r = r + component
+
+            bitString += component
+
         else:
-            raise error.SubstrateUnderrunError(
-                'No EOO seen before substrate ends'
-                )
-        return r, substrate
+            raise error.SubstrateUnderrunError('No EOO seen before substrate ends')
+
+        return bitString, substrate
+
 
 class OctetStringDecoder(AbstractSimpleDecoder):
     protoComponent = univ.OctetString('')
-    tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
-                     state, decodeFun, substrateFun):
+    supportConstructedForm = True
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         head, tail = substrate[:length], substrate[length:]
-        if tagSet[0][1] == tag.tagFormatSimple:    # XXX what tag to check?
+
+        if substrateFun:
+            return substrateFun(self._createComponent(asn1Spec, tagSet),
+                                substrate, length)
+
+        if tagSet[0].tagFormat == tag.tagFormatSimple:  # XXX what tag to check?
             return self._createComponent(asn1Spec, tagSet, head), tail
-        r = self._createComponent(asn1Spec, tagSet, '')
-        if substrateFun:
-            return substrateFun(r, substrate, length)
+
+        if not self.supportConstructedForm:
+            raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+
+        # All inner fragments are of the same type, treat them as octet string
+        substrateFun = self.substrateCollector
+
+        header = null
+
         while head:
-            component, head = decodeFun(head)
-            r = r + component
-        return r, tail
+            component, head = decodeFun(head, self.protoComponent,
+                                        substrateFun=substrateFun,
+                                        **options)
+            header += component
+
+        return self._createComponent(asn1Spec, tagSet, header), tail
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
-        r = self._createComponent(asn1Spec, tagSet, '')
-        if substrateFun:
-            return substrateFun(r, substrate, length)
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
+        if substrateFun and substrateFun is not self.substrateCollector:
+            asn1Object = self._createComponent(asn1Spec, tagSet)
+            return substrateFun(asn1Object, substrate, length)
+
+        # All inner fragments are of the same type, treat them as octet string
+        substrateFun = self.substrateCollector
+
+        header = null
+
         while substrate:
-            component, substrate = decodeFun(substrate)
-            if eoo.endOfOctets.isSameTypeWith(component) and \
-                    component == eoo.endOfOctets:
+            component, substrate = decodeFun(substrate,
+                                             self.protoComponent,
+                                             substrateFun=substrateFun,
+                                             allowEoo=True, **options)
+            if component is eoo.endOfOctets:
                 break
-            r = r + component
+            header += component
         else:
             raise error.SubstrateUnderrunError(
                 'No EOO seen before substrate ends'
-                )
-        return r, substrate
+            )
+
+        return self._createComponent(asn1Spec, tagSet, header), substrate
+
 
 class NullDecoder(AbstractSimpleDecoder):
     protoComponent = univ.Null('')
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+
+        if tagSet[0].tagFormat != tag.tagFormatSimple:
+            raise error.PyAsn1Error('Simple tag format expected')
+
         head, tail = substrate[:length], substrate[length:]
-        r = self._createComponent(asn1Spec, tagSet)
+
+        component = self._createComponent(asn1Spec, tagSet)
+
         if head:
             raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
-        return r, tail
+
+        return component, tail
+
 
 class ObjectIdentifierDecoder(AbstractSimpleDecoder):
     protoComponent = univ.ObjectIdentifier(())
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
-                     state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+        if tagSet[0].tagFormat != tag.tagFormatSimple:
+            raise error.PyAsn1Error('Simple tag format expected')
+
         head, tail = substrate[:length], substrate[length:]
         if not head:
             raise error.PyAsn1Error('Empty substrate')
 
-        # Get the first subid
-        subId = oct2int(head[0])
-        oid = divmod(subId, 40)
+        head = octs2ints(head)
 
-        index = 1
+        oid = ()
+        index = 0
         substrateLen = len(head)
         while index < substrateLen:
-            subId = oct2int(head[index])
-            index = index + 1
-            if subId == 128:
-                # ASN.1 spec forbids leading zeros (0x80) in sub-ID OID
-                # encoding, tolerating it opens a vulnerability.
-                # See http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf page 7
-                raise error.PyAsn1Error('Invalid leading 0x80 in sub-OID')
+            subId = head[index]
+            index += 1
+            if subId < 128:
+                oid += (subId,)
             elif subId > 128:
                 # Construct subid from a number of octets
                 nextSubId = subId
                 subId = 0
                 while nextSubId >= 128:
                     subId = (subId << 7) + (nextSubId & 0x7F)
                     if index >= substrateLen:
                         raise error.SubstrateUnderrunError(
                             'Short substrate for sub-OID past %s' % (oid,)
-                            )
-                    nextSubId = oct2int(head[index])
-                    index = index + 1
-                subId = (subId << 7) + nextSubId
-            oid = oid + (subId,)
+                        )
+                    nextSubId = head[index]
+                    index += 1
+                oid += ((subId << 7) + nextSubId,)
+            elif subId == 128:
+                # ASN.1 spec forbids leading zeros (0x80) in OID
+                # encoding, tolerating it opens a vulnerability. See
+                # http://www.cosic.esat.kuleuven.be/publications/article-1432.pdf
+                # page 7
+                raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
+
+        # Decode two leading arcs
+        if 0 <= oid[0] <= 39:
+            oid = (0,) + oid
+        elif 40 <= oid[0] <= 79:
+            oid = (1, oid[0] - 40) + oid[1:]
+        elif oid[0] >= 80:
+            oid = (2, oid[0] - 80) + oid[1:]
+        else:
+            raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
+
         return self._createComponent(asn1Spec, tagSet, oid), tail
 
+
 class RealDecoder(AbstractSimpleDecoder):
     protoComponent = univ.Real()
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+        if tagSet[0].tagFormat != tag.tagFormatSimple:
+            raise error.PyAsn1Error('Simple tag format expected')
+
         head, tail = substrate[:length], substrate[length:]
+
         if not head:
             return self._createComponent(asn1Spec, tagSet, 0.0), tail
-        fo = oct2int(head[0]); head = head[1:]
-        if fo & 0x80:  # binary enoding
+
+        fo = oct2int(head[0])
+        head = head[1:]
+        if fo & 0x80:  # binary encoding
+            if not head:
+                raise error.PyAsn1Error("Incomplete floating-point value")
             n = (fo & 0x03) + 1
             if n == 4:
                 n = oct2int(head[0])
+                head = head[1:]
             eo, head = head[:n], head[n:]
             if not eo or not head:
                 raise error.PyAsn1Error('Real exponent screwed')
             e = oct2int(eo[0]) & 0x80 and -1 or 0
-            while eo:         # exponent
+            while eo:  # exponent
                 e <<= 8
                 e |= oct2int(eo[0])
                 eo = eo[1:]
+            b = fo >> 4 & 0x03  # base bits
+            if b > 2:
+                raise error.PyAsn1Error('Illegal Real base')
+            if b == 1:  # encbase = 8
+                e *= 3
+            elif b == 2:  # encbase = 16
+                e *= 4
             p = 0
             while head:  # value
                 p <<= 8
                 p |= oct2int(head[0])
                 head = head[1:]
-            if fo & 0x40:    # sign bit
+            if fo & 0x40:  # sign bit
                 p = -p
+            sf = fo >> 2 & 0x03  # scale bits
+            p *= 2 ** sf
             value = (p, 2, e)
         elif fo & 0x40:  # infinite value
             value = fo & 0x01 and '-inf' or 'inf'
         elif fo & 0xc0 == 0:  # character encoding
+            if not head:
+                raise error.PyAsn1Error("Incomplete floating-point value")
             try:
                 if fo & 0x3 == 0x1:  # NR1
                     value = (int(head), 10, 0)
                 elif fo & 0x3 == 0x2:  # NR2
                     value = float(head)
                 elif fo & 0x3 == 0x3:  # NR3
                     value = float(head)
                 else:
                     raise error.SubstrateUnderrunError(
                         'Unknown NR (tag %s)' % fo
-                        )
+                    )
             except ValueError:
                 raise error.SubstrateUnderrunError(
                     'Bad character Real syntax'
-                    )
+                )
         else:
             raise error.SubstrateUnderrunError(
                 'Unknown encoding (tag %s)' % fo
-                )
+            )
         return self._createComponent(asn1Spec, tagSet, value), tail
-        
-class SequenceDecoder(AbstractConstructedDecoder):
-    protoComponent = univ.Sequence()
-    def _getComponentTagMap(self, r, idx):
-        try:
-            return r.getComponentTagMapNearPosition(idx)
-        except error.PyAsn1Error:
-            return
+
+
+class AbstractConstructedDecoder(AbstractDecoder):
+    protoComponent = None
+
+
+class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
+    protoRecordComponent = None
+    protoSequenceComponent = None
 
-    def _getComponentPositionByType(self, r, t, idx):
-        return r.getComponentPositionNearType(t, idx)
-    
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
-        head, tail = substrate[:length], substrate[length:]
-        r = self._createComponent(asn1Spec, tagSet)
-        idx = 0
-        if substrateFun:
-            return substrateFun(r, substrate, length)
-        while head:
-            asn1Spec = self._getComponentTagMap(r, idx)
-            component, head = decodeFun(head, asn1Spec)
-            idx = self._getComponentPositionByType(
-                r, component.getEffectiveTagSet(), idx
-                )
-            r.setComponentByPosition(idx, component, asn1Spec is None)
-            idx = idx + 1
-        r.setDefaultComponents()
-        r.verifySizeSpec()
-        return r, tail
+    def _getComponentTagMap(self, asn1Object, idx):
+        raise NotImplementedError()
+
+    def _getComponentPositionByType(self, asn1Object, tagSet, idx):
+        raise NotImplementedError()
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
-        r = self._createComponent(asn1Spec, tagSet)
-        if substrateFun:
-            return substrateFun(r, substrate, length)
-        idx = 0
+    def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):
+        components = []
+        componentTypes = set()
         while substrate:
-            asn1Spec = self._getComponentTagMap(r, idx)
-            component, substrate = decodeFun(substrate, asn1Spec)
-            if eoo.endOfOctets.isSameTypeWith(component) and \
-                    component == eoo.endOfOctets:
+            component, substrate = decodeFun(substrate, **options)
+            if component is eoo.endOfOctets:
                 break
-            idx = self._getComponentPositionByType(
-                r, component.getEffectiveTagSet(), idx
-                )            
-            r.setComponentByPosition(idx, component, asn1Spec is None)
-            idx = idx + 1                
+            components.append(component)
+            componentTypes.add(component.tagSet)
+
+        # Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF
+        # The heuristics is:
+        # * 0-1 component -> likely SEQUENCE OF/SET OF
+        # * 1+ components of the same type -> likely SEQUENCE OF/SET OF
+        # * otherwise -> likely SEQUENCE/SET
+        if len(components) > 1 or len(componentTypes) > 1:
+            protoComponent = self.protoRecordComponent
         else:
-            raise error.SubstrateUnderrunError(
-                'No EOO seen before substrate ends'
+            protoComponent = self.protoSequenceComponent
+
+        asn1Object = protoComponent.clone(
+            # construct tagSet from base tag from prototype ASN.1 object
+            # and additional tags recovered from the substrate
+            tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
+        )
+
+        for idx, component in enumerate(components):
+            asn1Object.setComponentByPosition(
+                idx, component,
+                verifyConstraints=False,
+                matchTags=False, matchConstraints=False
+            )
+
+        return asn1Object, substrate
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+        if tagSet[0].tagFormat != tag.tagFormatConstructed:
+            raise error.PyAsn1Error('Constructed tag format expected')
+
+        head, tail = substrate[:length], substrate[length:]
+
+        if substrateFun is not None:
+            if asn1Spec is not None:
+                asn1Object = asn1Spec.clone()
+            elif self.protoComponent is not None:
+                asn1Object = self.protoComponent.clone(tagSet=tagSet)
+            else:
+                asn1Object = self.protoRecordComponent, self.protoSequenceComponent
+
+            return substrateFun(asn1Object, substrate, length)
+
+        if asn1Spec is None:
+            asn1Object, trailing = self._decodeComponents(
+                head, tagSet=tagSet, decodeFun=decodeFun, **options
+            )
+            if trailing:
+                raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing))
+            return asn1Object, tail
+
+        asn1Object = asn1Spec.clone()
+
+        if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):
+
+            namedTypes = asn1Object.componentType
+
+            isSetType = asn1Object.typeId == univ.Set.typeId
+            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+
+            seenIndices = set()
+            idx = 0
+            while head:
+                if not namedTypes:
+                    asn1Spec = None
+                elif isSetType:
+                    asn1Spec = namedTypes.tagMapUnique
+                else:
+                    try:
+                        if isDeterministic:
+                            asn1Spec = namedTypes[idx].asn1Object
+                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+                            asn1Spec = namedTypes.getTagMapNearPosition(idx)
+                        else:
+                            asn1Spec = namedTypes[idx].asn1Object
+                    except IndexError:
+                        raise error.PyAsn1Error(
+                            'Excessive components decoded at %r' % (asn1Object,)
+                        )
+
+                component, head = decodeFun(head, asn1Spec, **options)
+
+                if not isDeterministic and namedTypes:
+                    if isSetType:
+                        idx = namedTypes.getPositionByType(component.effectiveTagSet)
+                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
+
+                asn1Object.setComponentByPosition(
+                    idx, component,
+                    verifyConstraints=False,
+                    matchTags=False, matchConstraints=False
+                )
+
+                seenIndices.add(idx)
+                idx += 1
+
+            if namedTypes:
+                if not namedTypes.requiredComponents.issubset(seenIndices):
+                    raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
+            else:
+                asn1Object.verifySizeSpec()
+
+        else:
+            asn1Spec = asn1Object.componentType
+            idx = 0
+            while head:
+                component, head = decodeFun(head, asn1Spec, **options)
+                asn1Object.setComponentByPosition(
+                    idx, component,
+                    verifyConstraints=False,
+                    matchTags=False, matchConstraints=False
                 )
-        r.setDefaultComponents()
-        r.verifySizeSpec()
-        return r, substrate
+                idx += 1
+
+            asn1Object.verifySizeSpec()
+
+        return asn1Object, tail
+
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
+        if tagSet[0].tagFormat != tag.tagFormatConstructed:
+            raise error.PyAsn1Error('Constructed tag format expected')
+
+        if substrateFun is not None:
+            if asn1Spec is not None:
+                asn1Object = asn1Spec.clone()
+            elif self.protoComponent is not None:
+                asn1Object = self.protoComponent.clone(tagSet=tagSet)
+            else:
+                asn1Object = self.protoRecordComponent, self.protoSequenceComponent
+
+            return substrateFun(asn1Object, substrate, length)
+
+        if asn1Spec is None:
+            return self._decodeComponents(
+                substrate, tagSet=tagSet, decodeFun=decodeFun, allowEoo=True, **options
+            )
+
+        asn1Object = asn1Spec.clone()
+
+        if asn1Object.typeId in (univ.Sequence.typeId, univ.Set.typeId):
+
+            namedTypes = asn1Object.componentType
+
+            isSetType = asn1Object.typeId == univ.Set.typeId
+            isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+
+            seenIndices = set()
+            idx = 0
+            while substrate:
+                if len(namedTypes) <= idx:
+                    asn1Spec = None
+                elif isSetType:
+                    asn1Spec = namedTypes.tagMapUnique
+                else:
+                    try:
+                        if isDeterministic:
+                            asn1Spec = namedTypes[idx].asn1Object
+                        elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+                            asn1Spec = namedTypes.getTagMapNearPosition(idx)
+                        else:
+                            asn1Spec = namedTypes[idx].asn1Object
+                    except IndexError:
+                        raise error.PyAsn1Error(
+                            'Excessive components decoded at %r' % (asn1Object,)
+                        )
+
+                component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
+                if component is eoo.endOfOctets:
+                    break
+
+                if not isDeterministic and namedTypes:
+                    if isSetType:
+                        idx = namedTypes.getPositionByType(component.effectiveTagSet)
+                    elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
+                        idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
+
+                asn1Object.setComponentByPosition(
+                    idx, component,
+                    verifyConstraints=False,
+                    matchTags=False, matchConstraints=False
+                )
 
-class SequenceOfDecoder(AbstractConstructedDecoder):
-    protoComponent = univ.SequenceOf()    
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
+                seenIndices.add(idx)
+                idx += 1
+
+            else:
+                raise error.SubstrateUnderrunError(
+                    'No EOO seen before substrate ends'
+                )
+
+            if namedTypes:
+                if not namedTypes.requiredComponents.issubset(seenIndices):
+                    raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
+            else:
+                asn1Object.verifySizeSpec()
+
+        else:
+            asn1Spec = asn1Object.componentType
+            idx = 0
+            while substrate:
+                component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
+                if component is eoo.endOfOctets:
+                    break
+                asn1Object.setComponentByPosition(
+                    idx, component,
+                    verifyConstraints=False,
+                    matchTags=False, matchConstraints=False
+                )
+                idx += 1
+            else:
+                raise error.SubstrateUnderrunError(
+                    'No EOO seen before substrate ends'
+                )
+            asn1Object.verifySizeSpec()
+
+        return asn1Object, substrate
+
+
+class SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder):
+    protoRecordComponent = univ.Sequence()
+    protoSequenceComponent = univ.SequenceOf()
+
+
+class SequenceDecoder(SequenceOrSequenceOfDecoder):
+    protoComponent = univ.Sequence()
+
+
+class SequenceOfDecoder(SequenceOrSequenceOfDecoder):
+    protoComponent = univ.SequenceOf()
+
+
+class SetOrSetOfDecoder(UniversalConstructedTypeDecoder):
+    protoRecordComponent = univ.Set()
+    protoSequenceComponent = univ.SetOf()
+
+
+class SetDecoder(SetOrSetOfDecoder):
+    protoComponent = univ.Set()
+
+
+
+class SetOfDecoder(SetOrSetOfDecoder):
+    protoComponent = univ.SetOf()
+
+
+class ChoiceDecoder(AbstractConstructedDecoder):
+    protoComponent = univ.Choice()
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         head, tail = substrate[:length], substrate[length:]
-        r = self._createComponent(asn1Spec, tagSet)
+        if asn1Spec is None:
+            asn1Object = self.protoComponent.clone(tagSet=tagSet)
+        else:
+            asn1Object = asn1Spec.clone()
         if substrateFun:
-            return substrateFun(r, substrate, length)
-        asn1Spec = r.getComponentType()
-        idx = 0
-        while head:
-            component, head = decodeFun(head, asn1Spec)
-            r.setComponentByPosition(idx, component, asn1Spec is None)
-            idx = idx + 1
-        r.verifySizeSpec()
-        return r, tail
+            return substrateFun(asn1Object, substrate, length)
+        if asn1Object.tagSet == tagSet:  # explicitly tagged Choice
+            component, head = decodeFun(
+                head, asn1Object.componentTagMap, **options
+            )
+        else:
+            component, head = decodeFun(
+                head, asn1Object.componentTagMap,
+                tagSet, length, state, **options
+            )
+        effectiveTagSet = component.effectiveTagSet
+        asn1Object.setComponentByType(
+            effectiveTagSet, component,
+            verifyConstraints=False,
+            matchTags=False, matchConstraints=False,
+            innerFlag=False
+        )
+        return asn1Object, tail
+
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
+        if asn1Spec is None:
+            asn1Object = self.protoComponent.clone(tagSet=tagSet)
+        else:
+            asn1Object = asn1Spec.clone()
+        if substrateFun:
+            return substrateFun(asn1Object, substrate, length)
+        if asn1Object.tagSet == tagSet:  # explicitly tagged Choice
+            component, substrate = decodeFun(
+                substrate, asn1Object.componentType.tagMapUnique, **options
+            )
+            # eat up EOO marker
+            eooMarker, substrate = decodeFun(
+                substrate, allowEoo=True, **options
+            )
+            if eooMarker is not eoo.endOfOctets:
+                raise error.PyAsn1Error('No EOO seen before substrate ends')
+        else:
+            component, substrate = decodeFun(
+                substrate, asn1Object.componentType.tagMapUnique,
+                tagSet, length, state, **options
+            )
+        effectiveTagSet = component.effectiveTagSet
+        asn1Object.setComponentByType(
+            effectiveTagSet, component,
+            verifyConstraints=False,
+            matchTags=False, matchConstraints=False,
+            innerFlag=False
+        )
+        return asn1Object, substrate
 
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
-        r = self._createComponent(asn1Spec, tagSet)
+
+class AnyDecoder(AbstractSimpleDecoder):
+    protoComponent = univ.Any()
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
+        if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet:
+            fullSubstrate = options['fullSubstrate']
+
+            # untagged Any container, recover inner header substrate
+            length += len(fullSubstrate) - len(substrate)
+            substrate = fullSubstrate
+
         if substrateFun:
-            return substrateFun(r, substrate, length)
-        asn1Spec = r.getComponentType()
-        idx = 0
+            return substrateFun(self._createComponent(asn1Spec, tagSet),
+                                substrate, length)
+
+        head, tail = substrate[:length], substrate[length:]
+
+        return self._createComponent(asn1Spec, tagSet, value=head), tail
+
+    def indefLenValueDecoder(self, substrate, asn1Spec,
+                             tagSet=None, length=None, state=None,
+                             decodeFun=None, substrateFun=None,
+                             **options):
+        if asn1Spec is not None and tagSet == asn1Spec.tagSet:
+            # tagged Any type -- consume header substrate
+            header = null
+        else:
+            fullSubstrate = options['fullSubstrate']
+
+            # untagged Any, recover header substrate
+            header = fullSubstrate[:-len(substrate)]
+
+        # Any components do not inherit initial tag
+        asn1Spec = self.protoComponent
+
+        if substrateFun and substrateFun is not self.substrateCollector:
+            asn1Object = self._createComponent(asn1Spec, tagSet)
+            return substrateFun(asn1Object, header + substrate, length + len(header))
+
+        # All inner fragments are of the same type, treat them as octet string
+        substrateFun = self.substrateCollector
+
         while substrate:
-            component, substrate = decodeFun(substrate, asn1Spec)
-            if eoo.endOfOctets.isSameTypeWith(component) and \
-                    component == eoo.endOfOctets:
+            component, substrate = decodeFun(substrate, asn1Spec,
+                                             substrateFun=substrateFun,
+                                             allowEoo=True, **options)
+            if component is eoo.endOfOctets:
                 break
-            r.setComponentByPosition(idx, component, asn1Spec is None)
-            idx = idx + 1                
+            header += component
         else:
             raise error.SubstrateUnderrunError(
                 'No EOO seen before substrate ends'
-                )
-        r.verifySizeSpec()
-        return r, substrate
-
-class SetDecoder(SequenceDecoder):
-    protoComponent = univ.Set()
-    def _getComponentTagMap(self, r, idx):
-        return r.getComponentTagMap()
-
-    def _getComponentPositionByType(self, r, t, idx):
-        nextIdx = r.getComponentPositionByType(t)
-        if nextIdx is None:
-            return idx
-        else:
-            return nextIdx
-    
-class SetOfDecoder(SequenceOfDecoder):
-    protoComponent = univ.SetOf()
-    
-class ChoiceDecoder(AbstractConstructedDecoder):
-    protoComponent = univ.Choice()
-    tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
-        head, tail = substrate[:length], substrate[length:]
-        r = self._createComponent(asn1Spec, tagSet)
-        if substrateFun:
-            return substrateFun(r, substrate, length)
-        if r.getTagSet() == tagSet: # explicitly tagged Choice
-            component, head = decodeFun(
-                head, r.getComponentTagMap()
-                )
-        else:
-            component, head = decodeFun(
-                head, r.getComponentTagMap(), tagSet, length, state
-                )
-        if isinstance(component, univ.Choice):
-            effectiveTagSet = component.getEffectiveTagSet()
-        else:
-            effectiveTagSet = component.getTagSet()
-        r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None)
-        return r, tail
-
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
-        r = self._createComponent(asn1Spec, tagSet)
+            )
         if substrateFun:
-            return substrateFun(r, substrate, length)
-        if r.getTagSet() == tagSet: # explicitly tagged Choice
-            component, substrate = decodeFun(substrate, r.getComponentTagMap())
-            eooMarker, substrate = decodeFun(substrate)  # eat up EOO marker
-            if not eoo.endOfOctets.isSameTypeWith(eooMarker) or \
-                    eooMarker != eoo.endOfOctets:
-                raise error.PyAsn1Error('No EOO seen before substrate ends')
+            return header, substrate
         else:
-            component, substrate= decodeFun(
-                substrate, r.getComponentTagMap(), tagSet, length, state
-            )
-        if isinstance(component, univ.Choice):
-            effectiveTagSet = component.getEffectiveTagSet()
-        else:
-            effectiveTagSet = component.getTagSet()
-        r.setComponentByType(effectiveTagSet, component, 0, asn1Spec is None)
-        return r, substrate
+            return self._createComponent(asn1Spec, tagSet, header), substrate
 
-class AnyDecoder(AbstractSimpleDecoder):
-    protoComponent = univ.Any()
-    tagFormats = (tag.tagFormatSimple, tag.tagFormatConstructed)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                     length, state, decodeFun, substrateFun):
-        if asn1Spec is None or \
-               asn1Spec is not None and tagSet != asn1Spec.getTagSet():
-            # untagged Any container, recover inner header substrate
-            length = length + len(fullSubstrate) - len(substrate)
-            substrate = fullSubstrate
-        if substrateFun:
-            return substrateFun(self._createComponent(asn1Spec, tagSet),
-                                substrate, length)
-        head, tail = substrate[:length], substrate[length:]
-        return self._createComponent(asn1Spec, tagSet, value=head), tail
-
-    def indefLenValueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet,
-                             length, state, decodeFun, substrateFun):
-        if asn1Spec is not None and tagSet == asn1Spec.getTagSet():
-            # tagged Any type -- consume header substrate
-            header = ''
-        else:
-            # untagged Any, recover header substrate
-            header = fullSubstrate[:-len(substrate)]
-
-        r = self._createComponent(asn1Spec, tagSet, header)
-
-        # Any components do not inherit initial tag
-        asn1Spec = self.protoComponent
-        
-        if substrateFun:
-            return substrateFun(r, substrate, length)
-        while substrate:
-            component, substrate = decodeFun(substrate, asn1Spec)
-            if eoo.endOfOctets.isSameTypeWith(component) and \
-                    component == eoo.endOfOctets:
-                break
-            r = r + component
-        else:
-            raise error.SubstrateUnderrunError(
-                'No EOO seen before substrate ends'
-                )
-        return r, substrate
 
 # character string types
 class UTF8StringDecoder(OctetStringDecoder):
     protoComponent = char.UTF8String()
+
+
 class NumericStringDecoder(OctetStringDecoder):
     protoComponent = char.NumericString()
+
+
 class PrintableStringDecoder(OctetStringDecoder):
     protoComponent = char.PrintableString()
+
+
 class TeletexStringDecoder(OctetStringDecoder):
     protoComponent = char.TeletexString()
+
+
 class VideotexStringDecoder(OctetStringDecoder):
     protoComponent = char.VideotexString()
+
+
 class IA5StringDecoder(OctetStringDecoder):
     protoComponent = char.IA5String()
+
+
 class GraphicStringDecoder(OctetStringDecoder):
     protoComponent = char.GraphicString()
+
+
 class VisibleStringDecoder(OctetStringDecoder):
     protoComponent = char.VisibleString()
+
+
 class GeneralStringDecoder(OctetStringDecoder):
     protoComponent = char.GeneralString()
+
+
 class UniversalStringDecoder(OctetStringDecoder):
     protoComponent = char.UniversalString()
+
+
 class BMPStringDecoder(OctetStringDecoder):
     protoComponent = char.BMPString()
 
+
 # "useful" types
+class ObjectDescriptorDecoder(OctetStringDecoder):
+    protoComponent = useful.ObjectDescriptor()
+
+
 class GeneralizedTimeDecoder(OctetStringDecoder):
     protoComponent = useful.GeneralizedTime()
+
+
 class UTCTimeDecoder(OctetStringDecoder):
     protoComponent = useful.UTCTime()
 
+
 tagMap = {
-    eoo.endOfOctets.tagSet: EndOfOctetsDecoder(),
     univ.Integer.tagSet: IntegerDecoder(),
     univ.Boolean.tagSet: BooleanDecoder(),
     univ.BitString.tagSet: BitStringDecoder(),
     univ.OctetString.tagSet: OctetStringDecoder(),
     univ.Null.tagSet: NullDecoder(),
     univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
     univ.Enumerated.tagSet: IntegerDecoder(),
     univ.Real.tagSet: RealDecoder(),
-    univ.Sequence.tagSet: SequenceDecoder(),  # conflicts with SequenceOf
-    univ.Set.tagSet: SetDecoder(),            # conflicts with SetOf
-    univ.Choice.tagSet: ChoiceDecoder(),      # conflicts with Any
+    univ.Sequence.tagSet: SequenceOrSequenceOfDecoder(),  # conflicts with SequenceOf
+    univ.Set.tagSet: SetOrSetOfDecoder(),  # conflicts with SetOf
+    univ.Choice.tagSet: ChoiceDecoder(),  # conflicts with Any
     # character string types
     char.UTF8String.tagSet: UTF8StringDecoder(),
     char.NumericString.tagSet: NumericStringDecoder(),
     char.PrintableString.tagSet: PrintableStringDecoder(),
     char.TeletexString.tagSet: TeletexStringDecoder(),
     char.VideotexString.tagSet: VideotexStringDecoder(),
     char.IA5String.tagSet: IA5StringDecoder(),
     char.GraphicString.tagSet: GraphicStringDecoder(),
     char.VisibleString.tagSet: VisibleStringDecoder(),
     char.GeneralString.tagSet: GeneralStringDecoder(),
     char.UniversalString.tagSet: UniversalStringDecoder(),
     char.BMPString.tagSet: BMPStringDecoder(),
     # useful types
+    useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),
     useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
     useful.UTCTime.tagSet: UTCTimeDecoder()
-    }
+}
 
 # Type-to-codec map for ambiguous ASN.1 types
 typeMap = {
     univ.Set.typeId: SetDecoder(),
     univ.SetOf.typeId: SetOfDecoder(),
     univ.Sequence.typeId: SequenceDecoder(),
     univ.SequenceOf.typeId: SequenceOfDecoder(),
     univ.Choice.typeId: ChoiceDecoder(),
     univ.Any.typeId: AnyDecoder()
-    }
+}
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+    if typeDecoder.protoComponent is not None:
+        typeId = typeDecoder.protoComponent.__class__.typeId
+        if typeId is not None and typeId not in typeMap:
+            typeMap[typeId] = typeDecoder
+
 
-( stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
-  stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
-  stDumpRawValue, stErrorCondition, stStop ) = [x for x in range(10)]
+(stDecodeTag,
+ stDecodeLength,
+ stGetValueDecoder,
+ stGetValueDecoderByAsn1Spec,
+ stGetValueDecoderByTag,
+ stTryAsExplicitTag,
+ stDecodeValue,
+ stDumpRawValue,
+ stErrorCondition,
+ stStop) = [x for x in range(10)]
 
-class Decoder:
+
+class Decoder(object):
     defaultErrorState = stErrorCondition
-#    defaultErrorState = stDumpRawValue
+    #    defaultErrorState = stDumpRawValue
     defaultRawDecoder = AnyDecoder()
+    supportIndefLength = True
+
+    # noinspection PyDefaultArgument
     def __init__(self, tagMap, typeMap={}):
         self.__tagMap = tagMap
         self.__typeMap = typeMap
-        self.__endOfOctetsTagSet = eoo.endOfOctets.getTagSet()
         # Tag & TagSet objects caches
         self.__tagCache = {}
         self.__tagSetCache = {}
-        
-    def __call__(self, substrate, asn1Spec=None, tagSet=None,
-                 length=None, state=stDecodeTag, recursiveFlag=1,
-                 substrateFun=None):
+        self.__eooSentinel = ints2octs((0, 0))
+
+    def __call__(self, substrate, asn1Spec=None,
+                 tagSet=None, length=None, state=stDecodeTag,
+                 decodeFun=None, substrateFun=None,
+                 **options):
+
         if debug.logger & debug.flagDecoder:
-            debug.logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
+            logger = debug.logger
+        else:
+            logger = None
+
+        if logger:
+            logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
+
+        allowEoo = options.pop('allowEoo', False)
+
+        # Look for end-of-octets sentinel
+        if allowEoo and self.supportIndefLength:
+            if substrate[:2] == self.__eooSentinel:
+                if logger:
+                    logger('end-of-octets sentinel found')
+                return eoo.endOfOctets, substrate[2:]
+
+        value = noValue
+
+        tagMap = self.__tagMap
+        typeMap = self.__typeMap
+        tagCache = self.__tagCache
+        tagSetCache = self.__tagSetCache
+
         fullSubstrate = substrate
-        while state != stStop:
-            if state == stDecodeTag:
-                # Decode tag
+
+        while state is not stStop:
+            if state is stDecodeTag:
                 if not substrate:
                     raise error.SubstrateUnderrunError(
                         'Short octet stream on tag decoding'
-                        )
-                if not isOctetsType(substrate) and \
-                   not isinstance(substrate, univ.OctetString):
-                    raise error.PyAsn1Error('Bad octet stream type')
-                
+                    )
+                # Decode tag
+                isShortTag = True
                 firstOctet = substrate[0]
                 substrate = substrate[1:]
-                if firstOctet in self.__tagCache:
-                    lastTag = self.__tagCache[firstOctet]
-                else:
-                    t = oct2int(firstOctet)
-                    tagClass = t&0xC0
-                    tagFormat = t&0x20
-                    tagId = t&0x1F
+                try:
+                    lastTag = tagCache[firstOctet]
+                except KeyError:
+                    integerTag = oct2int(firstOctet)
+                    tagClass = integerTag & 0xC0
+                    tagFormat = integerTag & 0x20
+                    tagId = integerTag & 0x1F
                     if tagId == 0x1F:
+                        isShortTag = False
+                        lengthOctetIdx = 0
                         tagId = 0
-                        while 1:
-                            if not substrate:
-                                raise error.SubstrateUnderrunError(
-                                    'Short octet stream on long tag decoding'
-                                    )
-                            t = oct2int(substrate[0])
-                            tagId = tagId << 7 | (t&0x7F)
-                            substrate = substrate[1:]
-                            if not t&0x80:
-                                break
+                        try:
+                            while True:
+                                integerTag = oct2int(substrate[lengthOctetIdx])
+                                lengthOctetIdx += 1
+                                tagId <<= 7
+                                tagId |= (integerTag & 0x7F)
+                                if not integerTag & 0x80:
+                                    break
+                            substrate = substrate[lengthOctetIdx:]
+                        except IndexError:
+                            raise error.SubstrateUnderrunError(
+                                'Short octet stream on long tag decoding'
+                            )
                     lastTag = tag.Tag(
                         tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
-                        )
-                    if tagId < 31:
+                    )
+                    if isShortTag:
                         # cache short tags
-                        self.__tagCache[firstOctet] = lastTag
+                        tagCache[firstOctet] = lastTag
                 if tagSet is None:
-                    if firstOctet in self.__tagSetCache:
-                        tagSet = self.__tagSetCache[firstOctet]
+                    if isShortTag:
+                        try:
+                            tagSet = tagSetCache[firstOctet]
+                        except KeyError:
+                            # base tag not recovered
+                            tagSet = tag.TagSet((), lastTag)
+                            tagSetCache[firstOctet] = tagSet
                     else:
-                        # base tag not recovered
                         tagSet = tag.TagSet((), lastTag)
-                        if firstOctet in self.__tagCache:
-                            self.__tagSetCache[firstOctet] = tagSet
                 else:
                     tagSet = lastTag + tagSet
                 state = stDecodeLength
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('tag decoded into %r, decoding length' % tagSet)
-            if state == stDecodeLength:
+                if logger:
+                    logger('tag decoded into %s, decoding length' % tagSet)
+            if state is stDecodeLength:
                 # Decode length
                 if not substrate:
-                     raise error.SubstrateUnderrunError(
-                         'Short octet stream on length decoding'
-                         )
-                firstOctet  = oct2int(substrate[0])
-                if firstOctet == 128:
+                    raise error.SubstrateUnderrunError(
+                        'Short octet stream on length decoding'
+                    )
+                firstOctet = oct2int(substrate[0])
+                if firstOctet < 128:
                     size = 1
-                    length = -1
-                elif firstOctet < 128:
-                    length, size = firstOctet, 1
-                else:
+                    length = firstOctet
+                elif firstOctet > 128:
                     size = firstOctet & 0x7F
                     # encoded in size bytes
-                    length = 0
-                    lengthString = substrate[1:size+1]
+                    encodedLength = octs2ints(substrate[1:size + 1])
                     # missing check on maximum size, which shouldn't be a
                     # problem, we can handle more than is possible
-                    if len(lengthString) != size:
+                    if len(encodedLength) != size:
                         raise error.SubstrateUnderrunError(
-                            '%s<%s at %s' %
-                            (size, len(lengthString), tagSet)
-                            )
-                    for char in lengthString:
-                        length = (length << 8) | oct2int(char)
-                    size = size + 1
+                            '%s<%s at %s' % (size, len(encodedLength), tagSet)
+                        )
+                    length = 0
+                    for lengthOctet in encodedLength:
+                        length <<= 8
+                        length |= lengthOctet
+                    size += 1
+                else:
+                    size = 1
+                    length = -1
+
                 substrate = substrate[size:]
-                if length != -1 and len(substrate) < length:
-                    raise error.SubstrateUnderrunError(
-                        '%d-octet short' % (length - len(substrate))
-                        )
+                if length == -1:
+                    if not self.supportIndefLength:
+                        raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
+                else:
+                    if len(substrate) < length:
+                        raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))
                 state = stGetValueDecoder
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
-            if state == stGetValueDecoder:
+                if logger:
+                    logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
+            if state is stGetValueDecoder:
                 if asn1Spec is None:
                     state = stGetValueDecoderByTag
                 else:
                     state = stGetValueDecoderByAsn1Spec
             #
             # There're two ways of creating subtypes in ASN.1 what influences
             # decoder operation. These methods are:
             # 1) Either base types used in or no IMPLICIT tagging has been
@@ -687,122 +1065,156 @@ class Decoder:
             # The first case allows for complete tag recovery from substrate
             # while the second one requires original ASN.1 type spec for
             # decoding.
             #
             # In either case a set of tags (tagSet) is coming from substrate
             # in an incremental, tag-by-tag fashion (this is the case of
             # EXPLICIT tag which is most basic). Outermost tag comes first
             # from the wire.
-            #            
-            if state == stGetValueDecoderByTag:
-                if tagSet in self.__tagMap:
-                    concreteDecoder = self.__tagMap[tagSet]
-                else:
+            #
+            if state is stGetValueDecoderByTag:
+                try:
+                    concreteDecoder = tagMap[tagSet]
+                except KeyError:
                     concreteDecoder = None
                 if concreteDecoder:
                     state = stDecodeValue
                 else:
-                    _k = tagSet[:1]
-                    if _k in self.__tagMap:
-                        concreteDecoder = self.__tagMap[_k]
-                    else:
+                    try:
+                        concreteDecoder = tagMap[tagSet[:1]]
+                    except KeyError:
                         concreteDecoder = None
                     if concreteDecoder:
                         state = stDecodeValue
                     else:
                         state = stTryAsExplicitTag
-                if debug.logger and debug.logger & debug.flagDecoder:
-                    debug.logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
+                if logger:
+                    logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
                     debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
-            if state == stGetValueDecoderByAsn1Spec:
-                if isinstance(asn1Spec, (dict, tagmap.TagMap)):
-                    if tagSet in asn1Spec:
-                        __chosenSpec = asn1Spec[tagSet]
-                    else:
-                        __chosenSpec = None
-                    if debug.logger and debug.logger & debug.flagDecoder:
-                        debug.logger('candidate ASN.1 spec is a map of:')
-                        for t, v in asn1Spec.getPosMap().items():
-                            debug.logger('  %r -> %s' % (t, v.__class__.__name__))
-                        if asn1Spec.getNegMap():
-                            debug.logger('but neither of: ')
-                            for i in asn1Spec.getNegMap().items():
-                                debug.logger('  %r -> %s' % (t, v.__class__.__name__))
-                        debug.logger('new candidate ASN.1 spec is %s, chosen by %r' % (__chosenSpec is None and '<none>' or __chosenSpec.__class__.__name__, tagSet))
+            if state is stGetValueDecoderByAsn1Spec:
+                if asn1Spec.__class__ is tagmap.TagMap:
+                    try:
+                        chosenSpec = asn1Spec[tagSet]
+                    except KeyError:
+                        chosenSpec = None
+                    if logger:
+                        logger('candidate ASN.1 spec is a map of:')
+                        for firstOctet, v in asn1Spec.presentTypes.items():
+                            logger('  %s -> %s' % (firstOctet, v.__class__.__name__))
+                        if asn1Spec.skipTypes:
+                            logger('but neither of: ')
+                            for firstOctet, v in asn1Spec.skipTypes.items():
+                                logger('  %s -> %s' % (firstOctet, v.__class__.__name__))
+                        logger('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
+                elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
+                    chosenSpec = asn1Spec
+                    if logger:
+                        logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
                 else:
-                    __chosenSpec = asn1Spec
-                    debug.logger and debug.logger & debug.flagDecoder and debug.logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
-                if __chosenSpec is not None and (
-                       tagSet == __chosenSpec.getTagSet() or \
-                       tagSet in __chosenSpec.getTagMap()
-                       ):
-                    # use base type for codec lookup to recover untagged types
-                    baseTagSet = __chosenSpec.baseTagSet
-                    if __chosenSpec.typeId is not None and \
-                           __chosenSpec.typeId in self.__typeMap:
-                        # ambiguous type
-                        concreteDecoder = self.__typeMap[__chosenSpec.typeId]
-                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen for an ambiguous type by type ID %s' % (__chosenSpec.typeId,))
-                    elif baseTagSet in self.__tagMap:
-                        # base type or tagged subtype
-                        concreteDecoder = self.__tagMap[baseTagSet]
-                        debug.logger and debug.logger & debug.flagDecoder and debug.logger('value decoder chosen by base %r' % (baseTagSet,))
-                    else:
-                        concreteDecoder = None
+                    chosenSpec = None
+
+                if chosenSpec is not None:
+                    try:
+                        # ambiguous type or just faster codec lookup
+                        concreteDecoder = typeMap[chosenSpec.typeId]
+                        if logger:
+                            logger('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
+                    except KeyError:
+                        # use base type for codec lookup to recover untagged types
+                        baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag,  chosenSpec.tagSet.baseTag)
+                        try:
+                            # base type or tagged subtype
+                            concreteDecoder = tagMap[baseTagSet]
+                            if logger:
+                                logger('value decoder chosen by base %s' % (baseTagSet,))
+                        except KeyError:
+                            concreteDecoder = None
                     if concreteDecoder:
-                        asn1Spec = __chosenSpec
+                        asn1Spec = chosenSpec
                         state = stDecodeValue
                     else:
                         state = stTryAsExplicitTag
-                elif tagSet == self.__endOfOctetsTagSet:
-                    concreteDecoder = self.__tagMap[tagSet]
-                    state = stDecodeValue
-                    debug.logger and debug.logger & debug.flagDecoder and debug.logger('end-of-octets found')
                 else:
                     concreteDecoder = None
                     state = stTryAsExplicitTag
-                if debug.logger and debug.logger & debug.flagDecoder:
-                    debug.logger('codec %s chosen by ASN.1 spec, decoding %s' % (state == stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as explicit tag'))
-                    debug.scope.push(__chosenSpec is None and '?' or __chosenSpec.__class__.__name__)
-            if state == stTryAsExplicitTag:
-                if tagSet and \
-                       tagSet[0][1] == tag.tagFormatConstructed and \
-                       tagSet[0][0] != tag.tagClassUniversal:
+                if logger:
+                    logger('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
+                    debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
+            if state is stDecodeValue:
+                if not options.get('recursiveFlag', True) and not substrateFun:  # deprecate this
+                    substrateFun = lambda a, b, c: (a, b[:c])
+
+                options.update(fullSubstrate=fullSubstrate)
+
+                if length == -1:  # indef length
+                    value, substrate = concreteDecoder.indefLenValueDecoder(
+                        substrate, asn1Spec,
+                        tagSet, length, stGetValueDecoder,
+                        self, substrateFun,
+                        **options
+                    )
+                else:
+                    value, substrate = concreteDecoder.valueDecoder(
+                        substrate, asn1Spec,
+                        tagSet, length, stGetValueDecoder,
+                        self, substrateFun,
+                        **options
+                    )
+                if logger:
+                    logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
+                state = stStop
+                break
+            if state is stTryAsExplicitTag:
+                if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal:
                     # Assume explicit tagging
                     concreteDecoder = explicitTagDecoder
                     state = stDecodeValue
-                else:                    
+                else:
                     concreteDecoder = None
                     state = self.defaultErrorState
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state == stDecodeValue and 'value' or 'as failure'))
-            if state == stDumpRawValue:
+                if logger:
+                    logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
+            if state is stDumpRawValue:
                 concreteDecoder = self.defaultRawDecoder
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
+                if logger:
+                    logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
                 state = stDecodeValue
-            if state == stDecodeValue:
-                if recursiveFlag == 0 and not substrateFun: # legacy
-                    substrateFun = lambda a,b,c: (a,b[:c])
-                if length == -1:  # indef length
-                    value, substrate = concreteDecoder.indefLenValueDecoder(
-                        fullSubstrate, substrate, asn1Spec, tagSet, length,
-                        stGetValueDecoder, self, substrateFun
-                        )
-                else:
-                    value, substrate = concreteDecoder.valueDecoder(
-                        fullSubstrate, substrate, asn1Spec, tagSet, length,
-                        stGetValueDecoder, self, substrateFun
-                        )
-                state = stStop
-                debug.logger and debug.logger & debug.flagDecoder and debug.logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, value.prettyPrint(), substrate and debug.hexdump(substrate) or '<none>'))
-            if state == stErrorCondition:
+            if state is stErrorCondition:
                 raise error.PyAsn1Error(
-                    '%r not in asn1Spec: %r' % (tagSet, asn1Spec)
-                    )
-        if debug.logger and debug.logger & debug.flagDecoder:
+                    '%s not in asn1Spec: %r' % (tagSet, asn1Spec)
+                )
+        if logger:
             debug.scope.pop()
-            debug.logger('decoder left scope %s, call completed' % debug.scope)
+            logger('decoder left scope %s, call completed' % debug.scope)
         return value, substrate
-            
+
+
+#: Turns BER octet stream into an ASN.1 object.
+#:
+#: Takes BER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     BER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#:     being decoded, *asn1Spec* may or may not be required. Most common reason for
+#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#:     A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On decoding errors
 decode = Decoder(tagMap, typeMap)
 
 # XXX
 # non-recursive decoding; return position rather than substrate
--- a/third_party/python/pyasn1/pyasn1/codec/ber/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/encoder.py
@@ -1,290 +1,411 @@
-# BER encoder
-from pyasn1.type import base, tag, univ, char, useful
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import tag, univ, char, useful
 from pyasn1.codec.ber import eoo
 from pyasn1.compat.octets import int2oct, oct2int, ints2octs, null, str2octs
+from pyasn1.compat.integer import to_bytes
 from pyasn1 import debug, error
 
-class Error(Exception): pass
+__all__ = ['encode']
 
-class AbstractItemEncoder:
+
+class AbstractItemEncoder(object):
     supportIndefLenMode = 1
-    def encodeTag(self, t, isConstructed):
-        tagClass, tagFormat, tagId = t.asTuple()  # this is a hotspot
-        v = tagClass | tagFormat
+
+    # An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)`
+    eooIntegerSubstrate = (0, 0)
+    eooOctetsSubstrate = ints2octs(eooIntegerSubstrate)
+
+    # noinspection PyMethodMayBeStatic
+    def encodeTag(self, singleTag, isConstructed):
+        tagClass, tagFormat, tagId = singleTag
+        encodedTag = tagClass | tagFormat
         if isConstructed:
-            v = v|tag.tagFormatConstructed
+            encodedTag |= tag.tagFormatConstructed
         if tagId < 31:
-            return int2oct(v|tagId)
+            return encodedTag | tagId,
         else:
-            s = int2oct(tagId&0x7f)
-            tagId = tagId >> 7
+            substrate = tagId & 0x7f,
+            tagId >>= 7
             while tagId:
-                s = int2oct(0x80|(tagId&0x7f)) + s
-                tagId = tagId >> 7
-            return int2oct(v|0x1F) + s
+                substrate = (0x80 | (tagId & 0x7f),) + substrate
+                tagId >>= 7
+            return (encodedTag | 0x1F,) + substrate
 
     def encodeLength(self, length, defMode):
         if not defMode and self.supportIndefLenMode:
-            return int2oct(0x80)
+            return (0x80,)
         if length < 0x80:
-            return int2oct(length)
+            return length,
         else:
-            substrate = null
+            substrate = ()
             while length:
-                substrate = int2oct(length&0xff) + substrate
-                length = length >> 8
+                substrate = (length & 0xff,) + substrate
+                length >>= 8
             substrateLen = len(substrate)
             if substrateLen > 126:
-                raise Error('Length octets overflow (%d)' % substrateLen)
-            return int2oct(0x80 | substrateLen) + substrate
+                raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen)
+            return (0x80 | substrateLen,) + substrate
+
+    def encodeValue(self, value, encodeFun, **options):
+        raise error.PyAsn1Error('Not implemented')
+
+    def encode(self, value, encodeFun, **options):
+
+        tagSet = value.tagSet
 
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        raise Error('Not implemented')
+        # untagged item?
+        if not tagSet:
+            substrate, isConstructed, isOctets = self.encodeValue(
+                value, encodeFun, **options
+            )
+            return substrate
+
+        defMode = options.get('defMode', True)
+
+        for idx, singleTag in enumerate(tagSet.superTags):
+
+            defModeOverride = defMode
 
-    def _encodeEndOfOctets(self, encodeFun, defMode):
-        if defMode or not self.supportIndefLenMode:
-            return null
-        else:
-            return encodeFun(eoo.endOfOctets, defMode)
-        
-    def encode(self, encodeFun, value, defMode, maxChunkSize):
-        substrate, isConstructed = self.encodeValue(
-            encodeFun, value, defMode, maxChunkSize
-            )
-        tagSet = value.getTagSet()
-        if tagSet:
-            if not isConstructed:  # primitive form implies definite mode
-                defMode = 1
-            return self.encodeTag(
-                tagSet[-1], isConstructed
-                ) + self.encodeLength(
-                len(substrate), defMode
-                ) + substrate + self._encodeEndOfOctets(encodeFun, defMode)
-        else:
-            return substrate  # untagged value
+            # base tag?
+            if not idx:
+                substrate, isConstructed, isOctets = self.encodeValue(
+                    value, encodeFun, **options
+                )
+
+                if options.get('ifNotEmpty', False) and not substrate:
+                    return substrate
+
+                # primitive form implies definite mode
+                if not isConstructed:
+                    defModeOverride = True
+
+            header = self.encodeTag(singleTag, isConstructed)
+            header += self.encodeLength(len(substrate), defModeOverride)
+
+            if isOctets:
+                substrate = ints2octs(header) + substrate
+
+                if not defModeOverride:
+                    substrate += self.eooOctetsSubstrate
+
+            else:
+                substrate = header + substrate
+
+                if not defModeOverride:
+                    substrate += self.eooIntegerSubstrate
+
+        if not isOctets:
+            substrate = ints2octs(substrate)
+
+        return substrate
+
 
 class EndOfOctetsEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        return null, 0
+    def encodeValue(self, value, encodeFun, **options):
+        return null, False, True
 
-class ExplicitlyTaggedItemEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        if isinstance(value, base.AbstractConstructedAsn1Item):
-            value = value.clone(tagSet=value.getTagSet()[:-1],
-                                cloneValueFlag=1)
-        else:
-            value = value.clone(tagSet=value.getTagSet()[:-1])
-        return encodeFun(value, defMode, maxChunkSize), 1
-
-explicitlyTaggedItemEncoder = ExplicitlyTaggedItemEncoder()
 
 class BooleanEncoder(AbstractItemEncoder):
-    supportIndefLenMode = 0
-    _true = ints2octs((1,))
-    _false = ints2octs((0,))
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        return value and self._true or self._false, 0
+    supportIndefLenMode = False
+
+    def encodeValue(self, value, encodeFun, **options):
+        return value and (1,) or (0,), False, False
+
 
 class IntegerEncoder(AbstractItemEncoder):
-    supportIndefLenMode = 0
+    supportIndefLenMode = False
     supportCompactZero = False
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        if value == 0:  # shortcut for zero value
+
+    def encodeValue(self, value, encodeFun, **options):
+        if value == 0:
+            # de-facto way to encode zero
             if self.supportCompactZero:
-                # this seems to be a correct way for encoding zeros
-                return null, 0
+                return (), False, False
             else:
-                # this seems to be a widespread way for encoding zeros
-                return ints2octs((0,)), 0
-        octets = []
-        value = int(value) # to save on ops on asn1 type
-        while 1:
-            octets.insert(0, value & 0xff)
-            if value == 0 or value == -1:
-                break
-            value = value >> 8
-        if value == 0 and octets[0] & 0x80:
-            octets.insert(0, 0)
-        while len(octets) > 1 and \
-                  (octets[0] == 0 and octets[1] & 0x80 == 0 or \
-                   octets[0] == 0xff and octets[1] & 0x80 != 0):
-            del octets[0]
-        return ints2octs(octets), 0
+                return (0,), False, False
+
+        return to_bytes(int(value), signed=True), False, True
+
 
 class BitStringEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        if not maxChunkSize or len(value) <= maxChunkSize*8:
-            r = {}; l = len(value); p = 0; j = 7
-            while p < l:
-                i, j = divmod(p, 8)
-                r[i] = r.get(i,0) | value[p]<<(7-j)
-                p = p + 1
-            keys = list(r); keys.sort()
-            return int2oct(7-j) + ints2octs([r[k] for k in keys]), 0
+    def encodeValue(self, value, encodeFun, **options):
+        valueLength = len(value)
+        if valueLength % 8:
+            alignedValue = value << (8 - valueLength % 8)
         else:
-            pos = 0; substrate = null
-            while 1:
-                # count in octets
-                v = value.clone(value[pos*8:pos*8+maxChunkSize*8])
-                if not v:
-                    break
-                substrate = substrate + encodeFun(v, defMode, maxChunkSize)
-                pos = pos + maxChunkSize
-            return substrate, 1
+            alignedValue = value
+
+        maxChunkSize = options.get('maxChunkSize', 0)
+        if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8:
+            substrate = alignedValue.asOctets()
+            return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True
+
+        # strip off explicit tags
+        alignedValue = alignedValue.clone(
+            tagSet=tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+        )
+
+        stop = 0
+        substrate = null
+        while stop < valueLength:
+            start = stop
+            stop = min(start + maxChunkSize * 8, valueLength)
+            substrate += encodeFun(alignedValue[start:stop], **options)
+
+        return substrate, True, True
+
 
 class OctetStringEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+    def encodeValue(self, value, encodeFun, **options):
+        maxChunkSize = options.get('maxChunkSize', 0)
         if not maxChunkSize or len(value) <= maxChunkSize:
-            return value.asOctets(), 0
+            return value.asOctets(), False, True
+
         else:
-            pos = 0; substrate = null
-            while 1:
-                v = value.clone(value[pos:pos+maxChunkSize])
-                if not v:
+            # will strip off explicit tags
+            baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+            pos = 0
+            substrate = null
+            while True:
+                chunk = value.clone(value[pos:pos + maxChunkSize],
+                                    tagSet=baseTagSet)
+                if not chunk:
                     break
-                substrate = substrate + encodeFun(v, defMode, maxChunkSize)
-                pos = pos + maxChunkSize
-            return substrate, 1
+                substrate += encodeFun(chunk, **options)
+                pos += maxChunkSize
+
+            return substrate, True, True
+
 
 class NullEncoder(AbstractItemEncoder):
-    supportIndefLenMode = 0
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        return null, 0
+    supportIndefLenMode = False
+
+    def encodeValue(self, value, encodeFun, **options):
+        return null, False, True
+
 
 class ObjectIdentifierEncoder(AbstractItemEncoder):
-    supportIndefLenMode = 0
-    precomputedValues = {
-        (1, 3, 6, 1, 2): (43, 6, 1, 2),        
-        (1, 3, 6, 1, 4): (43, 6, 1, 4)
-        }
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):    
+    supportIndefLenMode = False
+
+    def encodeValue(self, value, encodeFun, **options):
         oid = value.asTuple()
-        if oid[:5] in self.precomputedValues:
-            octets = self.precomputedValues[oid[:5]]
-            index = 5
-        else:
-            if len(oid) < 2:
-                raise error.PyAsn1Error('Short OID %s' % (value,))
+
+        # Build the first pair
+        try:
+            first = oid[0]
+            second = oid[1]
+
+        except IndexError:
+            raise error.PyAsn1Error('Short OID %s' % (value,))
 
-            # Build the first twos
-            if oid[0] > 6 or oid[1] > 39 or oid[0] == 6 and oid[1] > 15:
-                raise error.PyAsn1Error(
-                    'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)
-                    )
-            octets = (oid[0] * 40 + oid[1],)
-            index = 2
+        if 0 <= second <= 39:
+            if first == 1:
+                oid = (second + 40,) + oid[2:]
+            elif first == 0:
+                oid = (second,) + oid[2:]
+            elif first == 2:
+                oid = (second + 80,) + oid[2:]
+            else:
+                raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
+        elif first == 2:
+            oid = (second + 80,) + oid[2:]
+        else:
+            raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
 
-        # Cycle through subids
-        for subid in oid[index:]:
-            if subid > -1 and subid < 128:
+        octets = ()
+
+        # Cycle through subIds
+        for subOid in oid:
+            if 0 <= subOid <= 127:
                 # Optimize for the common case
-                octets = octets + (subid & 0x7f,)
-            elif subid < 0 or subid > 0xFFFFFFFF:
-                raise error.PyAsn1Error(
-                    'SubId overflow %s in %s' % (subid, value)
-                    )
-            else:
+                octets += (subOid,)
+            elif subOid > 127:
                 # Pack large Sub-Object IDs
-                res = (subid & 0x7f,)
-                subid = subid >> 7
-                while subid > 0:
-                    res = (0x80 | (subid & 0x7f),) + res
-                    subid = subid >> 7 
+                res = (subOid & 0x7f,)
+                subOid >>= 7
+                while subOid:
+                    res = (0x80 | (subOid & 0x7f),) + res
+                    subOid >>= 7
                 # Add packed Sub-Object ID to resulted Object ID
                 octets += res
-                
-        return ints2octs(octets), 0
+            else:
+                raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))
+
+        return octets, False, False
+
 
 class RealEncoder(AbstractItemEncoder):
     supportIndefLenMode = 0
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        if value.isPlusInfinity():
-            return int2oct(0x40), 0
-        if value.isMinusInfinity():
-            return int2oct(0x41), 0
+    binEncBase = 2  # set to None to choose encoding base automatically
+
+    @staticmethod
+    def _dropFloatingPoint(m, encbase, e):
+        ms, es = 1, 1
+        if m < 0:
+            ms = -1  # mantissa sign
+        if e < 0:
+            es = -1  # exponenta sign 
+        m *= ms
+        if encbase == 8:
+            m *= 2 ** (abs(e) % 3 * es)
+            e = abs(e) // 3 * es
+        elif encbase == 16:
+            m *= 2 ** (abs(e) % 4 * es)
+            e = abs(e) // 4 * es
+
+        while True:
+            if int(m) != m:
+                m *= encbase
+                e -= 1
+                continue
+            break
+        return ms, int(m), encbase, e
+
+    def _chooseEncBase(self, value):
+        m, b, e = value
+        encBase = [2, 8, 16]
+        if value.binEncBase in encBase:
+            return self._dropFloatingPoint(m, value.binEncBase, e)
+        elif self.binEncBase in encBase:
+            return self._dropFloatingPoint(m, self.binEncBase, e)
+        # auto choosing base 2/8/16 
+        mantissa = [m, m, m]
+        exponenta = [e, e, e]
+        sign = 1
+        encbase = 2
+        e = float('inf')
+        for i in range(3):
+            (sign,
+             mantissa[i],
+             encBase[i],
+             exponenta[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponenta[i])
+            if abs(exponenta[i]) < abs(e) or (abs(exponenta[i]) == abs(e) and mantissa[i] < m):
+                e = exponenta[i]
+                m = int(mantissa[i])
+                encbase = encBase[i]
+        return sign, m, encbase, e
+
+    def encodeValue(self, value, encodeFun, **options):
+        if value.isPlusInf:
+            return (0x40,), False, False
+        if value.isMinusInf:
+            return (0x41,), False, False
         m, b, e = value
         if not m:
-            return null, 0
+            return null, False, True
         if b == 10:
-            return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), 0
+            return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True
         elif b == 2:
-            fo = 0x80                 # binary enoding
-            if m < 0:
-                fo = fo | 0x40  # sign bit
-                m = -m
-            while int(m) != m: # drop floating point
-                m *= 2
-                e -= 1
-            while m & 0x1 == 0: # mantissa normalization
+            fo = 0x80  # binary encoding
+            ms, m, encbase, e = self._chooseEncBase(value)
+            if ms < 0:  # mantissa sign
+                fo |= 0x40  # sign bit
+            # exponenta & mantissa normalization
+            if encbase == 2:
+                while m & 0x1 == 0:
+                    m >>= 1
+                    e += 1
+            elif encbase == 8:
+                while m & 0x7 == 0:
+                    m >>= 3
+                    e += 1
+                fo |= 0x10
+            else:  # encbase = 16
+                while m & 0xf == 0:
+                    m >>= 4
+                    e += 1
+                fo |= 0x20
+            sf = 0  # scale factor
+            while m & 0x1 == 0:
                 m >>= 1
-                e += 1
+                sf += 1
+            if sf > 3:
+                raise error.PyAsn1Error('Scale factor overflow')  # bug if raised
+            fo |= sf << 2
             eo = null
-            while e not in (0, -1):
-                eo = int2oct(e&0xff) + eo
-                e >>= 8
-            if e == 0 and eo and oct2int(eo[0]) & 0x80:
-                eo = int2oct(0) + eo
+            if e == 0 or e == -1:
+                eo = int2oct(e & 0xff)
+            else:
+                while e not in (0, -1):
+                    eo = int2oct(e & 0xff) + eo
+                    e >>= 8
+                if e == 0 and eo and oct2int(eo[0]) & 0x80:
+                    eo = int2oct(0) + eo
+                if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
+                    eo = int2oct(0xff) + eo
             n = len(eo)
             if n > 0xff:
                 raise error.PyAsn1Error('Real exponent overflow')
             if n == 1:
                 pass
             elif n == 2:
                 fo |= 1
             elif n == 3:
                 fo |= 2
             else:
                 fo |= 3
-                eo = int2oct(n//0xff+1) + eo
+                eo = int2oct(n & 0xff) + eo
             po = null
             while m:
-                po = int2oct(m&0xff) + po
+                po = int2oct(m & 0xff) + po
                 m >>= 8
             substrate = int2oct(fo) + eo + po
-            return substrate, 0
+            return substrate, False, True
         else:
             raise error.PyAsn1Error('Prohibited Real base %s' % b)
 
+
 class SequenceEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        value.setDefaultComponents()
+    def encodeValue(self, value, encodeFun, **options):
         value.verifySizeSpec()
-        substrate = null; idx = len(value)
+
+        namedTypes = value.componentType
+        substrate = null
+
+        idx = len(value)
         while idx > 0:
-            idx = idx - 1
-            if value[idx] is None:  # Optional component
-                continue
-            component = value.getDefaultComponentByPosition(idx)
-            if component is not None and component == value[idx]:
-                continue
-            substrate = encodeFun(
-                value[idx], defMode, maxChunkSize
-                ) + substrate
-        return substrate, 1
+            idx -= 1
+            if namedTypes:
+                if namedTypes[idx].isOptional and not value[idx].isValue:
+                    continue
+                if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+                    continue
+            substrate = encodeFun(value[idx], **options) + substrate
+
+        return substrate, True, True
+
 
 class SequenceOfEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
+    def encodeValue(self, value, encodeFun, **options):
         value.verifySizeSpec()
-        substrate = null; idx = len(value)
+        substrate = null
+        idx = len(value)
         while idx > 0:
-            idx = idx - 1
-            substrate = encodeFun(
-                value[idx], defMode, maxChunkSize
-                ) + substrate
-        return substrate, 1
+            idx -= 1
+            substrate = encodeFun(value[idx], **options) + substrate
+        return substrate, True, True
+
 
 class ChoiceEncoder(AbstractItemEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        return encodeFun(value.getComponent(), defMode, maxChunkSize), 1
+    def encodeValue(self, value, encodeFun, **options):
+        return encodeFun(value.getComponent(), **options), True, True
+
 
 class AnyEncoder(OctetStringEncoder):
-    def encodeValue(self, encodeFun, value, defMode, maxChunkSize):
-        return value.asOctets(), defMode == 0
+    def encodeValue(self, value, encodeFun, **options):
+        return value.asOctets(), not options.get('defMode', True), True
+
 
 tagMap = {
     eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),
     univ.Boolean.tagSet: BooleanEncoder(),
     univ.Integer.tagSet: IntegerEncoder(),
     univ.BitString.tagSet: BitStringEncoder(),
     univ.OctetString.tagSet: OctetStringEncoder(),
     univ.Null.tagSet: NullEncoder(),
@@ -303,51 +424,125 @@ tagMap = {
     char.VideotexString.tagSet: OctetStringEncoder(),
     char.IA5String.tagSet: OctetStringEncoder(),
     char.GraphicString.tagSet: OctetStringEncoder(),
     char.VisibleString.tagSet: OctetStringEncoder(),
     char.GeneralString.tagSet: OctetStringEncoder(),
     char.UniversalString.tagSet: OctetStringEncoder(),
     char.BMPString.tagSet: OctetStringEncoder(),
     # useful types
+    useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
     useful.GeneralizedTime.tagSet: OctetStringEncoder(),
-    useful.UTCTime.tagSet: OctetStringEncoder()        
-    }
+    useful.UTCTime.tagSet: OctetStringEncoder()
+}
 
-# Type-to-codec map for ambiguous ASN.1 types
+# Put in ambiguous & non-ambiguous types for faster codec lookup
 typeMap = {
+    univ.Boolean.typeId: BooleanEncoder(),
+    univ.Integer.typeId: IntegerEncoder(),
+    univ.BitString.typeId: BitStringEncoder(),
+    univ.OctetString.typeId: OctetStringEncoder(),
+    univ.Null.typeId: NullEncoder(),
+    univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(),
+    univ.Enumerated.typeId: IntegerEncoder(),
+    univ.Real.typeId: RealEncoder(),
+    # Sequence & Set have same tags as SequenceOf & SetOf
     univ.Set.typeId: SequenceEncoder(),
     univ.SetOf.typeId: SequenceOfEncoder(),
     univ.Sequence.typeId: SequenceEncoder(),
     univ.SequenceOf.typeId: SequenceOfEncoder(),
     univ.Choice.typeId: ChoiceEncoder(),
-    univ.Any.typeId: AnyEncoder()
-    }
+    univ.Any.typeId: AnyEncoder(),
+    # character string types
+    char.UTF8String.typeId: OctetStringEncoder(),
+    char.NumericString.typeId: OctetStringEncoder(),
+    char.PrintableString.typeId: OctetStringEncoder(),
+    char.TeletexString.typeId: OctetStringEncoder(),
+    char.VideotexString.typeId: OctetStringEncoder(),
+    char.IA5String.typeId: OctetStringEncoder(),
+    char.GraphicString.typeId: OctetStringEncoder(),
+    char.VisibleString.typeId: OctetStringEncoder(),
+    char.GeneralString.typeId: OctetStringEncoder(),
+    char.UniversalString.typeId: OctetStringEncoder(),
+    char.BMPString.typeId: OctetStringEncoder(),
+    # useful types
+    useful.ObjectDescriptor.typeId: OctetStringEncoder(),
+    useful.GeneralizedTime.typeId: OctetStringEncoder(),
+    useful.UTCTime.typeId: OctetStringEncoder()
+}
 
-class Encoder:
+
+class Encoder(object):
+    fixedDefLengthMode = None
+    fixedChunkSize = None
+
+    # noinspection PyDefaultArgument
     def __init__(self, tagMap, typeMap={}):
         self.__tagMap = tagMap
         self.__typeMap = typeMap
 
-    def __call__(self, value, defMode=1, maxChunkSize=0):
-        debug.logger & debug.flagEncoder and debug.logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not defMode and 'in' or '', maxChunkSize, value.__class__.__name__, value.prettyPrint()))
-        tagSet = value.getTagSet()
-        if len(tagSet) > 1:
-            concreteEncoder = explicitlyTaggedItemEncoder
+    def __call__(self, value, **options):
+
+        if debug.logger & debug.flagEncoder:
+            logger = debug.logger
         else:
-            if value.typeId is not None and value.typeId in self.__typeMap:
-                concreteEncoder = self.__typeMap[value.typeId]
-            elif tagSet in self.__tagMap:
-                concreteEncoder = self.__tagMap[tagSet]
-            else:
-                tagSet = value.baseTagSet
-                if tagSet in self.__tagMap:
-                    concreteEncoder = self.__tagMap[tagSet]
-                else:
-                    raise Error('No encoder for %s' % (value,))
-        debug.logger & debug.flagEncoder and debug.logger('using value codec %s chosen by %r' % (concreteEncoder.__class__.__name__, tagSet))
-        substrate = concreteEncoder.encode(
-            self, value, defMode, maxChunkSize
-            )
-        debug.logger & debug.flagEncoder and debug.logger('built %s octets of substrate: %s\nencoder completed' % (len(substrate), debug.hexdump(substrate)))
+            logger = None
+
+        if logger:
+            logger('encoder called in %sdef mode, chunk size %s for type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), value.prettyPrintType(), value.prettyPrint()))
+
+        if self.fixedDefLengthMode is not None:
+            options.update(defMode=self.fixedDefLengthMode)
+
+        if self.fixedChunkSize is not None:
+            options.update(maxChunkSize=self.fixedChunkSize)
+
+        tagSet = value.tagSet
+
+        try:
+            concreteEncoder = self.__typeMap[value.typeId]
+
+        except KeyError:
+            # use base type for codec lookup to recover untagged types
+            baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+            try:
+                concreteEncoder = self.__tagMap[baseTagSet]
+
+            except KeyError:
+                raise error.PyAsn1Error('No encoder for %s' % (value,))
+
+        if logger:
+            logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
+
+        substrate = concreteEncoder.encode(value, self, **options)
+
+        if logger:
+            logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
+
         return substrate
 
+#: Turns ASN.1 object into BER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a BER octet stream.
+#:
+#: Parameters
+#: ----------
+#  value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#:     If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#:     Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On encoding errors
 encode = Encoder(tagMap, typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/ber/eoo.py
+++ b/third_party/python/pyasn1/pyasn1/codec/ber/eoo.py
@@ -1,8 +1,25 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.type import base, tag
 
+
 class EndOfOctets(base.AbstractSimpleAsn1Item):
     defaultValue = 0
     tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)
-        )
+    )
+
+    _instance = None
+
+    def __new__(cls, *args, **kwargs):
+        if cls._instance is None:
+            cls._instance = object.__new__(cls, *args, **kwargs)
+
+        return cls._instance
+
+
 endOfOctets = EndOfOctets()
--- a/third_party/python/pyasn1/pyasn1/codec/cer/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/cer/decoder.py
@@ -1,35 +1,90 @@
-# CER decoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.type import univ
 from pyasn1.codec.ber import decoder
 from pyasn1.compat.octets import oct2int
 from pyasn1 import error
 
+__all__ = ['decode']
+
+
 class BooleanDecoder(decoder.AbstractSimpleDecoder):
     protoComponent = univ.Boolean(0)
-    def valueDecoder(self, fullSubstrate, substrate, asn1Spec, tagSet, length,
-                     state, decodeFun, substrateFun):
+
+    def valueDecoder(self, substrate, asn1Spec,
+                     tagSet=None, length=None, state=None,
+                     decodeFun=None, substrateFun=None,
+                     **options):
         head, tail = substrate[:length], substrate[length:]
-        if not head:
-            raise error.PyAsn1Error('Empty substrate')
+        if not head or length != 1:
+            raise error.PyAsn1Error('Not single-octet Boolean payload')
         byte = oct2int(head[0])
         # CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
         # BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1 
         # in http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
         if byte == 0xff:
             value = 1
         elif byte == 0x00:
             value = 0
         else:
-            raise error.PyAsn1Error('Boolean CER violation: %s' % byte)
+            raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte)
         return self._createComponent(asn1Spec, tagSet, value), tail
 
+# TODO: prohibit non-canonical encoding
+BitStringDecoder = decoder.BitStringDecoder
+OctetStringDecoder = decoder.OctetStringDecoder
+RealDecoder = decoder.RealDecoder
+
 tagMap = decoder.tagMap.copy()
-tagMap.update({
-    univ.Boolean.tagSet: BooleanDecoder()
-    })
+tagMap.update(
+    {univ.Boolean.tagSet: BooleanDecoder(),
+     univ.BitString.tagSet: BitStringDecoder(),
+     univ.OctetString.tagSet: OctetStringDecoder(),
+     univ.Real.tagSet: RealDecoder()}
+)
+
+typeMap = decoder.typeMap.copy()
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+    if typeDecoder.protoComponent is not None:
+        typeId = typeDecoder.protoComponent.__class__.typeId
+        if typeId is not None and typeId not in typeMap:
+            typeMap[typeId] = typeDecoder
+
+
+class Decoder(decoder.Decoder):
+    pass
+
 
-typeMap = decoder.typeMap
-
-class Decoder(decoder.Decoder): pass
-
+#: Turns CER octet stream into an ASN.1 object.
+#:
+#: Takes CER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     CER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#:     being decoded, *asn1Spec* may or may not be required. Most common reason for
+#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#:     A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On decoding errors
 decode = Decoder(tagMap, decoder.typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/cer/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/cer/encoder.py
@@ -1,87 +1,221 @@
-# CER encoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.type import univ
+from pyasn1.type import useful
 from pyasn1.codec.ber import encoder
-from pyasn1.compat.octets import int2oct, null
+from pyasn1.compat.octets import str2octs, null
+from pyasn1 import error
+
+__all__ = ['encode']
+
 
 class BooleanEncoder(encoder.IntegerEncoder):
-    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
-        if client == 0:
-            substrate = int2oct(0)
+    def encodeValue(self, value, encodeFun, **options):
+        if value == 0:
+            substrate = (0,)
         else:
-            substrate = int2oct(255)
-        return substrate, 0
+            substrate = (255,)
+        return substrate, False, False
+
+
+class RealEncoder(encoder.RealEncoder):
+    def _chooseEncBase(self, value):
+        m, b, e = value
+        return self._dropFloatingPoint(m, b, e)
+
+
+# specialized GeneralStringEncoder here
+
+class TimeEncoderMixIn(object):
+    zchar, = str2octs('Z')
+    pluschar, = str2octs('+')
+    minuschar, = str2octs('-')
+    commachar, = str2octs(',')
+    minLength = 12
+    maxLength = 19
 
-class BitStringEncoder(encoder.BitStringEncoder):
-    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
-        return encoder.BitStringEncoder.encodeValue(
-            self, encodeFun, client, defMode, 1000
-            )
+    def encodeValue(self, value, encodeFun, **options):
+        # Encoding constraints:
+        # - minutes are mandatory, seconds are optional
+        # - subseconds must NOT be zero
+        # - no hanging fraction dot
+        # - time in UTC (Z)
+        # - only dot is allowed for fractions
+
+        octets = value.asOctets()
+
+        if not self.minLength < len(octets) < self.maxLength:
+            raise error.PyAsn1Error('Length constraint violated: %r' % value)
+
+        if self.pluschar in octets or self.minuschar in octets:
+            raise error.PyAsn1Error('Must be UTC time: %r' % octets)
+
+        if octets[-1] != self.zchar:
+            raise error.PyAsn1Error('Missing "Z" time zone specifier: %r' % octets)
 
-class OctetStringEncoder(encoder.OctetStringEncoder):
-    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
+        if self.commachar in octets:
+            raise error.PyAsn1Error('Comma in fractions disallowed: %r' % value)
+
+        options.update(maxChunkSize=1000)
+
         return encoder.OctetStringEncoder.encodeValue(
-            self, encodeFun, client, defMode, 1000
-            )
+            self, value, encodeFun, **options
+        )
+
 
-# specialized RealEncoder here
-# specialized GeneralStringEncoder here
-# specialized GeneralizedTimeEncoder here
-# specialized UTCTimeEncoder here
+class GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
+    minLength = 12
+    maxLength = 19
+
+
+class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
+    minLength = 10
+    maxLength = 14
+
 
 class SetOfEncoder(encoder.SequenceOfEncoder):
-    def encodeValue(self, encodeFun, client, defMode, maxChunkSize):
-        if isinstance(client, univ.SequenceAndSetBase):
-            client.setDefaultComponents()
-        client.verifySizeSpec()
-        substrate = null; idx = len(client)
-        # This is certainly a hack but how else do I distinguish SetOf
-        # from Set if they have the same tags&constraints?
-        if isinstance(client, univ.SequenceAndSetBase):
-            # Set
+    @staticmethod
+    def _sortComponents(components):
+        # sort by tags regardless of the Choice value (static sort)
+        return sorted(components, key=lambda x: isinstance(x, univ.Choice) and x.minTagSet or x.tagSet)
+
+    def encodeValue(self, value, encodeFun, **options):
+        value.verifySizeSpec()
+        substrate = null
+        idx = len(value)
+        if value.typeId == univ.Set.typeId:
+            namedTypes = value.componentType
             comps = []
+            compsMap = {}
             while idx > 0:
-                idx = idx - 1
-                if client[idx] is None:  # Optional component
-                    continue
-                if client.getDefaultComponentByPosition(idx) == client[idx]:
+                idx -= 1
+                if namedTypes:
+                    if namedTypes[idx].isOptional and not value[idx].isValue:
+                        continue
+                    if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+                        continue
+
+                comps.append(value[idx])
+                compsMap[id(value[idx])] = namedTypes and namedTypes[idx].isOptional
+
+            for comp in self._sortComponents(comps):
+                options.update(ifNotEmpty=compsMap[id(comp)])
+                substrate += encodeFun(comp, **options)
+        else:
+            components = [encodeFun(x, **options) for x in value]
+
+            # sort by serialized and padded components
+            if len(components) > 1:
+                zero = str2octs('\x00')
+                maxLen = max(map(len, components))
+                paddedComponents = [
+                    (x.ljust(maxLen, zero), x) for x in components
+                ]
+                paddedComponents.sort(key=lambda x: x[0])
+
+                components = [x[1] for x in paddedComponents]
+
+            substrate = null.join(components)
+
+        return substrate, True, True
+
+
+class SequenceEncoder(encoder.SequenceEncoder):
+    def encodeValue(self, value, encodeFun, **options):
+        value.verifySizeSpec()
+
+        namedTypes = value.componentType
+        substrate = null
+
+        idx = len(value)
+        while idx > 0:
+            idx -= 1
+            if namedTypes:
+                if namedTypes[idx].isOptional and not value[idx].isValue:
                     continue
-                comps.append(client[idx])
-            comps.sort(key=lambda x: isinstance(x, univ.Choice) and \
-                                     x.getMinTagSet() or x.getTagSet())
-            for c in comps:
-                substrate += encodeFun(c, defMode, maxChunkSize)
-        else:
-            # SetOf
-            compSubs = []
-            while idx > 0:
-                idx = idx - 1
-                compSubs.append(
-                    encodeFun(client[idx], defMode, maxChunkSize)
-                    )
-            compSubs.sort()  # perhaps padding's not needed
-            substrate = null
-            for compSub in compSubs:
-                substrate += compSub
-        return substrate, 1
+                if namedTypes[idx].isDefaulted and value[idx] == namedTypes[idx].asn1Object:
+                    continue
+
+            options.update(ifNotEmpty=namedTypes and namedTypes[idx].isOptional)
+
+            substrate = encodeFun(value[idx], **options) + substrate
+
+        return substrate, True, True
+
+
+class SequenceOfEncoder(encoder.SequenceOfEncoder):
+    def encodeValue(self, value, encodeFun, **options):
+        substrate = null
+        idx = len(value)
+
+        if options.get('ifNotEmpty', False) and not idx:
+            return substrate, True, True
+
+        value.verifySizeSpec()
+        while idx > 0:
+            idx -= 1
+            substrate = encodeFun(value[idx], **options) + substrate
+        return substrate, True, True
+
 
 tagMap = encoder.tagMap.copy()
 tagMap.update({
     univ.Boolean.tagSet: BooleanEncoder(),
-    univ.BitString.tagSet: BitStringEncoder(),
-    univ.OctetString.tagSet: OctetStringEncoder(),
-    univ.SetOf().tagSet: SetOfEncoder()  # conflcts with Set
-    })
+    univ.Real.tagSet: RealEncoder(),
+    useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(),
+    useful.UTCTime.tagSet: UTCTimeEncoder(),
+    # Sequence & Set have same tags as SequenceOf & SetOf
+    univ.SetOf.tagSet: SetOfEncoder(),
+    univ.Sequence.typeId: SequenceEncoder()
+})
 
 typeMap = encoder.typeMap.copy()
 typeMap.update({
+    univ.Boolean.typeId: BooleanEncoder(),
+    univ.Real.typeId: RealEncoder(),
+    useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(),
+    useful.UTCTime.typeId: UTCTimeEncoder(),
+    # Sequence & Set have same tags as SequenceOf & SetOf
     univ.Set.typeId: SetOfEncoder(),
-    univ.SetOf.typeId: SetOfEncoder()
-    })
+    univ.SetOf.typeId: SetOfEncoder(),
+    univ.Sequence.typeId: SequenceEncoder(),
+    univ.SequenceOf.typeId: SequenceOfEncoder()
+})
+
 
 class Encoder(encoder.Encoder):
-    def __call__(self, client, defMode=0, maxChunkSize=0):
-        return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
+    fixedDefLengthMode = False
+    fixedChunkSize = 1000
 
+#: Turns ASN.1 object into CER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a CER octet stream.
+#:
+#: Parameters
+#: ----------
+#  value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#:     If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#:     Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On encoding errors
 encode = Encoder(tagMap, typeMap)
 
 # EncoderFactory queries class instance and builds a map of tags -> encoders
--- a/third_party/python/pyasn1/pyasn1/codec/der/decoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/der/decoder.py
@@ -1,9 +1,70 @@
-# DER decoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.type import univ
 from pyasn1.codec.cer import decoder
 
-tagMap = decoder.tagMap
-typeMap = decoder.typeMap
-Decoder = decoder.Decoder
+__all__ = ['decode']
+
+
+class BitStringDecoder(decoder.BitStringDecoder):
+    supportConstructedForm = False
+
+
+class OctetStringDecoder(decoder.OctetStringDecoder):
+    supportConstructedForm = False
+
+# TODO: prohibit non-canonical encoding
+RealDecoder = decoder.RealDecoder
+
+tagMap = decoder.tagMap.copy()
+tagMap.update(
+    {univ.BitString.tagSet: BitStringDecoder(),
+     univ.OctetString.tagSet: OctetStringDecoder(),
+     univ.Real.tagSet: RealDecoder()}
+)
+
+typeMap = decoder.typeMap.copy()
+
+# Put in non-ambiguous types for faster codec lookup
+for typeDecoder in tagMap.values():
+    if typeDecoder.protoComponent is not None:
+        typeId = typeDecoder.protoComponent.__class__.typeId
+        if typeId is not None and typeId not in typeMap:
+            typeMap[typeId] = typeDecoder
+
 
+class Decoder(decoder.Decoder):
+    supportIndefLength = False
+
+
+#: Turns DER octet stream into an ASN.1 object.
+#:
+#: Takes DER octetstream and decode it into an ASN.1 object
+#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     DER octetstream
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#:     A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
+#:     being decoded, *asn1Spec* may or may not be required. Most common reason for
+#:     it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
+#:
+#: Returns
+#: -------
+#: : :py:class:`tuple`
+#:     A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     and the unprocessed trailing portion of the *substrate* (may be empty)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On decoding errors
 decode = Decoder(tagMap, typeMap)
--- a/third_party/python/pyasn1/pyasn1/codec/der/encoder.py
+++ b/third_party/python/pyasn1/pyasn1/codec/der/encoder.py
@@ -1,28 +1,62 @@
-# DER encoder
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.type import univ
 from pyasn1.codec.cer import encoder
 
+__all__ = ['encode']
+
+
 class SetOfEncoder(encoder.SetOfEncoder):
-    def _cmpSetComponents(self, c1, c2):
-        tagSet1 = isinstance(c1, univ.Choice) and \
-                  c1.getEffectiveTagSet() or c1.getTagSet()
-        tagSet2 = isinstance(c2, univ.Choice) and \
-                  c2.getEffectiveTagSet() or c2.getTagSet()        
-        return cmp(tagSet1, tagSet2)
+    @staticmethod
+    def _sortComponents(components):
+        # sort by tags depending on the actual Choice value (dynamic sort)
+        return sorted(components, key=lambda x: isinstance(x, univ.Choice) and x.getComponent().tagSet or x.tagSet)
 
 tagMap = encoder.tagMap.copy()
 tagMap.update({
-    # Overload CER encodrs with BER ones (a bit hackerish XXX)
-    univ.BitString.tagSet: encoder.encoder.BitStringEncoder(),
-    univ.OctetString.tagSet: encoder.encoder.OctetStringEncoder(),
     # Set & SetOf have same tags
-    univ.SetOf().tagSet: SetOfEncoder()
-    })
+    univ.SetOf.tagSet: SetOfEncoder()
+})
 
-typeMap = encoder.typeMap
+typeMap = encoder.typeMap.copy()
+typeMap.update({
+    # Set & SetOf have same tags
+    univ.Set.typeId: SetOfEncoder(),
+    univ.SetOf.typeId: SetOfEncoder()
+})
+
 
 class Encoder(encoder.Encoder):
-    def __call__(self, client, defMode=1, maxChunkSize=0):
-        return encoder.Encoder.__call__(self, client, defMode, maxChunkSize)
-        
+    fixedDefLengthMode = True
+    fixedChunkSize = 0
+
+#: Turns ASN.1 object into DER octet stream.
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a DER octet stream.
+#:
+#: Parameters
+#: ----------
+#  value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     A pyasn1 object to encode
+#:
+#: defMode: :py:class:`bool`
+#:     If `False`, produces indefinite length encoding
+#:
+#: maxChunkSize: :py:class:`int`
+#:     Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
+#:
+#: Returns
+#: -------
+#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
+#:     Given ASN.1 object encoded into BER octetstream
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On encoding errors
 encode = Encoder(tagMap, typeMap)
rename from third_party/python/pyasn1/test/__init__.py
rename to third_party/python/pyasn1/pyasn1/codec/native/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/codec/native/decoder.py
@@ -0,0 +1,194 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from pyasn1.type import base, univ, char, useful, tag
+from pyasn1 import debug, error
+
+__all__ = ['decode']
+
+
+class AbstractScalarDecoder(object):
+    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+        return asn1Spec.clone(pyObject)
+
+
+class BitStringDecoder(AbstractScalarDecoder):
+    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+        return asn1Spec.clone(univ.BitString.fromBinaryString(pyObject))
+
+
+class SequenceOrSetDecoder(object):
+    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+        asn1Value = asn1Spec.clone()
+
+        componentsTypes = asn1Spec.componentType
+
+        for field in asn1Value:
+            if field in pyObject:
+                asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
+
+        return asn1Value
+
+
+class SequenceOfOrSetOfDecoder(object):
+    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+        asn1Value = asn1Spec.clone()
+
+        for pyValue in pyObject:
+            asn1Value.append(decodeFun(pyValue, asn1Spec.componentType), **options)
+
+        return asn1Value
+
+
+class ChoiceDecoder(object):
+    def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
+        asn1Value = asn1Spec.clone()
+
+        componentsTypes = asn1Spec.componentType
+
+        for field in pyObject:
+            if field in componentsTypes:
+                asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
+                break
+
+        return asn1Value
+
+
+tagMap = {
+    univ.Integer.tagSet: AbstractScalarDecoder(),
+    univ.Boolean.tagSet: AbstractScalarDecoder(),
+    univ.BitString.tagSet: BitStringDecoder(),
+    univ.OctetString.tagSet: AbstractScalarDecoder(),
+    univ.Null.tagSet: AbstractScalarDecoder(),
+    univ.ObjectIdentifier.tagSet: AbstractScalarDecoder(),
+    univ.Enumerated.tagSet: AbstractScalarDecoder(),
+    univ.Real.tagSet: AbstractScalarDecoder(),
+    univ.Sequence.tagSet: SequenceOrSetDecoder(),  # conflicts with SequenceOf
+    univ.Set.tagSet: SequenceOrSetDecoder(),  # conflicts with SetOf
+    univ.Choice.tagSet: ChoiceDecoder(),  # conflicts with Any
+    # character string types
+    char.UTF8String.tagSet: AbstractScalarDecoder(),
+    char.NumericString.tagSet: AbstractScalarDecoder(),
+    char.PrintableString.tagSet: AbstractScalarDecoder(),
+    char.TeletexString.tagSet: AbstractScalarDecoder(),
+    char.VideotexString.tagSet: AbstractScalarDecoder(),
+    char.IA5String.tagSet: AbstractScalarDecoder(),
+    char.GraphicString.tagSet: AbstractScalarDecoder(),
+    char.VisibleString.tagSet: AbstractScalarDecoder(),
+    char.GeneralString.tagSet: AbstractScalarDecoder(),
+    char.UniversalString.tagSet: AbstractScalarDecoder(),
+    char.BMPString.tagSet: AbstractScalarDecoder(),
+    # useful types
+    useful.ObjectDescriptor.tagSet: AbstractScalarDecoder(),
+    useful.GeneralizedTime.tagSet: AbstractScalarDecoder(),
+    useful.UTCTime.tagSet: AbstractScalarDecoder()
+}
+
+# Put in ambiguous & non-ambiguous types for faster codec lookup
+typeMap = {
+    univ.Integer.typeId: AbstractScalarDecoder(),
+    univ.Boolean.typeId: AbstractScalarDecoder(),
+    univ.BitString.typeId: BitStringDecoder(),
+    univ.OctetString.typeId: AbstractScalarDecoder(),
+    univ.Null.typeId: AbstractScalarDecoder(),
+    univ.ObjectIdentifier.typeId: AbstractScalarDecoder(),
+    univ.Enumerated.typeId: AbstractScalarDecoder(),
+    univ.Real.typeId: AbstractScalarDecoder(),
+    # ambiguous base types
+    univ.Set.typeId: SequenceOrSetDecoder(),
+    univ.SetOf.typeId: SequenceOfOrSetOfDecoder(),
+    univ.Sequence.typeId: SequenceOrSetDecoder(),
+    univ.SequenceOf.typeId: SequenceOfOrSetOfDecoder(),
+    univ.Choice.typeId: ChoiceDecoder(),
+    univ.Any.typeId: AbstractScalarDecoder(),
+    # character string types
+    char.UTF8String.typeId: AbstractScalarDecoder(),
+    char.NumericString.typeId: AbstractScalarDecoder(),
+    char.PrintableString.typeId: AbstractScalarDecoder(),
+    char.TeletexString.typeId: AbstractScalarDecoder(),
+    char.VideotexString.typeId: AbstractScalarDecoder(),
+    char.IA5String.typeId: AbstractScalarDecoder(),
+    char.GraphicString.typeId: AbstractScalarDecoder(),
+    char.VisibleString.typeId: AbstractScalarDecoder(),
+    char.GeneralString.typeId: AbstractScalarDecoder(),
+    char.UniversalString.typeId: AbstractScalarDecoder(),
+    char.BMPString.typeId: AbstractScalarDecoder(),
+    # useful types
+    useful.ObjectDescriptor.typeId: AbstractScalarDecoder(),
+    useful.GeneralizedTime.typeId: AbstractScalarDecoder(),
+    useful.UTCTime.typeId: AbstractScalarDecoder()
+}
+
+
+class Decoder(object):
+
+    # noinspection PyDefaultArgument
+    def __init__(self, tagMap, typeMap):
+        self.__tagMap = tagMap
+        self.__typeMap = typeMap
+
+    def __call__(self, pyObject, asn1Spec, **options):
+        if debug.logger & debug.flagDecoder:
+            logger = debug.logger
+        else:
+            logger = None
+        if logger:
+            debug.scope.push(type(pyObject).__name__)
+            logger('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))
+
+        if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item):
+            raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)
+
+        try:
+            valueDecoder = self.__typeMap[asn1Spec.typeId]
+
+        except KeyError:
+            # use base type for codec lookup to recover untagged types
+            baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag)
+
+            try:
+                valueDecoder = self.__tagMap[baseTagSet]
+            except KeyError:
+                raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet)
+
+        if logger:
+            logger('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))
+
+        value = valueDecoder(pyObject, asn1Spec, self, **options)
+
+        if logger:
+            logger('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))
+            debug.scope.pop()
+
+        return value
+
+
+#: Turns Python objects of built-in types into ASN.1 objects.
+#:
+#: Takes Python objects of built-in types and turns them into a tree of
+#: ASN.1 objects (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
+#: may be a scalar or an arbitrary nested structure.
+#:
+#: Parameters
+#: ----------
+#: pyObject: :py:class:`object`
+#:     A scalar or nested Python objects
+#:
+#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#:     A pyasn1 type object to act as a template guiding the decoder. It is required
+#:     for successful interpretation of Python objects mapping into their ASN.1
+#:     representations.
+#:
+#: Returns
+#: -------
+#: : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+#:     A scalar or constructed pyasn1 object
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On decoding errors
+decode = Decoder(tagMap, typeMap)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/codec/native/encoder.py
@@ -0,0 +1,212 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    from collections import OrderedDict
+
+except ImportError:
+    OrderedDict = dict
+
+from pyasn1.type import base, univ, tag, char, useful
+from pyasn1 import debug, error
+
+__all__ = ['encode']
+
+
+class AbstractItemEncoder(object):
+    def encode(self, value, encodeFun, **options):
+        raise error.PyAsn1Error('Not implemented')
+
+
+class BooleanEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return bool(value)
+
+
+class IntegerEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return int(value)
+
+
+class BitStringEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return str(value)
+
+
+class OctetStringEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return value.asOctets()
+
+
+class TextStringEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return value.prettyPrint()
+
+
+class NullEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return None
+
+
+class ObjectIdentifierEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return str(value)
+
+
+class RealEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return float(value)
+
+
+class SetEncoder(AbstractItemEncoder):
+    protoDict = dict
+
+    def encode(self, value, encodeFun, **options):
+        value.verifySizeSpec()
+
+        namedTypes = value.componentType
+        substrate = self.protoDict()
+
+        for idx, (key, subValue) in enumerate(value.items()):
+            if namedTypes and namedTypes[idx].isOptional and not value[idx].isValue:
+                continue
+            substrate[key] = encodeFun(subValue, **options)
+        return substrate
+
+
+class SequenceEncoder(SetEncoder):
+    protoDict = OrderedDict
+
+
+class SequenceOfEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        value.verifySizeSpec()
+        return [encodeFun(x, **options) for x in value]
+
+
+class ChoiceEncoder(SequenceEncoder):
+    pass
+
+
+class AnyEncoder(AbstractItemEncoder):
+    def encode(self, value, encodeFun, **options):
+        return value.asOctets()
+
+
+tagMap = {
+    univ.Boolean.tagSet: BooleanEncoder(),
+    univ.Integer.tagSet: IntegerEncoder(),
+    univ.BitString.tagSet: BitStringEncoder(),
+    univ.OctetString.tagSet: OctetStringEncoder(),
+    univ.Null.tagSet: NullEncoder(),
+    univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),
+    univ.Enumerated.tagSet: IntegerEncoder(),
+    univ.Real.tagSet: RealEncoder(),
+    # Sequence & Set have same tags as SequenceOf & SetOf
+    univ.SequenceOf.tagSet: SequenceOfEncoder(),
+    univ.SetOf.tagSet: SequenceOfEncoder(),
+    univ.Choice.tagSet: ChoiceEncoder(),
+    # character string types
+    char.UTF8String.tagSet: TextStringEncoder(),
+    char.NumericString.tagSet: TextStringEncoder(),
+    char.PrintableString.tagSet: TextStringEncoder(),
+    char.TeletexString.tagSet: TextStringEncoder(),
+    char.VideotexString.tagSet: TextStringEncoder(),
+    char.IA5String.tagSet: TextStringEncoder(),
+    char.GraphicString.tagSet: TextStringEncoder(),
+    char.VisibleString.tagSet: TextStringEncoder(),
+    char.GeneralString.tagSet: TextStringEncoder(),
+    char.UniversalString.tagSet: TextStringEncoder(),
+    char.BMPString.tagSet: TextStringEncoder(),
+    # useful types
+    useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
+    useful.GeneralizedTime.tagSet: OctetStringEncoder(),
+    useful.UTCTime.tagSet: OctetStringEncoder()
+}
+
+# Type-to-codec map for ambiguous ASN.1 types
+typeMap = {
+    univ.Set.typeId: SetEncoder(),
+    univ.SetOf.typeId: SequenceOfEncoder(),
+    univ.Sequence.typeId: SequenceEncoder(),
+    univ.SequenceOf.typeId: SequenceOfEncoder(),
+    univ.Choice.typeId: ChoiceEncoder(),
+    univ.Any.typeId: AnyEncoder()
+}
+
+
+class Encoder(object):
+
+    # noinspection PyDefaultArgument
+    def __init__(self, tagMap, typeMap={}):
+        self.__tagMap = tagMap
+        self.__typeMap = typeMap
+
+    def __call__(self, value, **options):
+        if not isinstance(value, base.Asn1Item):
+            raise error.PyAsn1Error('value is not valid (should be an instance of an ASN.1 Item)')
+
+        if debug.logger & debug.flagEncoder:
+            logger = debug.logger
+        else:
+            logger = None
+
+        if logger:
+            debug.scope.push(type(value).__name__)
+            logger('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))
+
+        tagSet = value.tagSet
+
+        try:
+            concreteEncoder = self.__typeMap[value.typeId]
+
+        except KeyError:
+            # use base type for codec lookup to recover untagged types
+            baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
+
+            try:
+                concreteEncoder = self.__tagMap[baseTagSet]
+
+            except KeyError:
+                raise error.PyAsn1Error('No encoder for %s' % (value,))
+
+        if logger:
+            logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
+
+        pyObject = concreteEncoder.encode(value, self, **options)
+
+        if logger:
+            logger('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))
+            debug.scope.pop()
+
+        return pyObject
+
+
+#: Turns ASN.1 object into a Python built-in type object(s).
+#:
+#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#: walks all its components recursively and produces a Python built-in type or a tree
+#: of those.
+#:
+#: One exception is that instead of :py:class:`dict`, the :py:class:`OrderedDict`
+#: can be produced (whenever available) to preserve ordering of the components
+#: in ASN.1 SEQUENCE.
+#:
+#: Parameters
+#: ----------
+#  asn1Value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
+#:     pyasn1 object to encode (or a tree of them)
+#:
+#: Returns
+#: -------
+#: : :py:class:`object`
+#:     Python built-in type instance (or a tree of them)
+#:
+#: Raises
+#: ------
+#: : :py:class:`pyasn1.error.PyAsn1Error`
+#:     On encoding errors
+encode = Encoder(tagMap, typeMap)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/binary.py
@@ -0,0 +1,33 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+if version_info[0:2] < (2, 6):
+    def bin(value):
+        bitstring = []
+
+        if value > 0:
+            prefix = '0b'
+        elif value < 0:
+            prefix = '-0b'
+            value = abs(value)
+        else:
+            prefix = '0b0'
+
+        while value:
+            if value & 1 == 1:
+                bitstring.append('1')
+            else:
+                bitstring.append('0')
+
+            value >>= 1
+
+        bitstring.reverse()
+
+        return prefix + ''.join(bitstring)
+else:
+    bin = bin
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/calling.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+__all__ = ['callable']
+
+
+if (2, 7) < version_info[:2] < (3, 2):
+    import collections
+
+    def callable(x):
+        return isinstance(x, collections.Callable)
+
+else:
+
+    callable = callable
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/dateandtime.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+from datetime import datetime
+import time
+
+__all__ = ['strptime']
+
+
+if version_info[:2] <= (2, 4):
+
+    def strptime(text, dateFormat):
+        return datetime(*(time.strptime(text, dateFormat)[0:6]))
+
+else:
+
+    def strptime(text, dateFormat):
+        return datetime.strptime(text, dateFormat)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/integer.py
@@ -0,0 +1,108 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+    import platform
+    implementation = platform.python_implementation()
+
+except (ImportError, AttributeError):
+    implementation = 'CPython'
+
+from pyasn1.compat.octets import oct2int, null, ensureString
+
+if sys.version_info[0:2] < (3, 2) or implementation != 'CPython':
+    from binascii import a2b_hex, b2a_hex
+
+    if sys.version_info[0] > 2:
+        long = int
+
+    def from_bytes(octets, signed=False):
+        if not octets:
+            return 0
+
+        value = long(b2a_hex(ensureString(octets)), 16)
+
+        if signed and oct2int(octets[0]) & 0x80:
+            return value - (1 << len(octets) * 8)
+
+        return value
+
+    def to_bytes(value, signed=False, length=0):
+        if value < 0:
+            if signed:
+                bits = bitLength(value)
+
+                # two's complement form
+                maxValue = 1 << bits
+                valueToEncode = (value + maxValue) % maxValue
+
+            else:
+                raise OverflowError('can\'t convert negative int to unsigned')
+        elif value == 0 and length == 0:
+            return null
+        else:
+            bits = 0
+            valueToEncode = value
+
+        hexValue = hex(valueToEncode)[2:]
+        if hexValue.endswith('L'):
+            hexValue = hexValue[:-1]
+
+        if len(hexValue) & 1:
+            hexValue = '0' + hexValue
+
+        # padding may be needed for two's complement encoding
+        if value != valueToEncode or length:
+            hexLength = len(hexValue) * 4
+
+            padLength = max(length, bits)
+
+            if padLength > hexLength:
+                hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue
+            elif length and hexLength - length > 7:
+                raise OverflowError('int too big to convert')
+
+        firstOctet = int(hexValue[:2], 16)
+
+        if signed:
+            if firstOctet & 0x80:
+                if value >= 0:
+                    hexValue = '00' + hexValue
+            elif value < 0:
+                hexValue = 'ff' + hexValue
+
+        octets_value = a2b_hex(hexValue)
+
+        return octets_value
+
+    def bitLength(number):
+        # bits in unsigned number
+        hexValue = hex(abs(number))
+        bits = len(hexValue) - 2
+        if hexValue.endswith('L'):
+            bits -= 1
+        if bits & 1:
+            bits += 1
+        bits *= 4
+        # TODO: strip lhs zeros
+        return bits
+
+else:
+
+    def from_bytes(octets, signed=False):
+        return int.from_bytes(bytes(octets), 'big', signed=signed)
+
+    def to_bytes(value, signed=False, length=0):
+        length = max(value.bit_length(), length)
+
+        if signed and length % 8 == 0:
+            length += 1
+
+        return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed)
+
+    def bitLength(number):
+        return int(number).bit_length()
--- a/third_party/python/pyasn1/pyasn1/compat/octets.py
+++ b/third_party/python/pyasn1/pyasn1/compat/octets.py
@@ -1,20 +1,46 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from sys import version_info
 
 if version_info[0] <= 2:
     int2oct = chr
-    ints2octs = lambda s: ''.join([ int2oct(x) for x in s ])
+    # noinspection PyPep8
+    ints2octs = lambda s: ''.join([int2oct(x) for x in s])
     null = ''
     oct2int = ord
-    octs2ints = lambda s: [ oct2int(x) for x in s ]
+    # TODO: refactor to return a sequence of ints
+    # noinspection PyPep8
+    octs2ints = lambda s: [oct2int(x) for x in s]
+    # noinspection PyPep8
     str2octs = lambda x: x
+    # noinspection PyPep8
     octs2str = lambda x: x
+    # noinspection PyPep8
     isOctetsType = lambda s: isinstance(s, str)
+    # noinspection PyPep8
+    isStringType = lambda s: isinstance(s, (str, unicode))
+    # noinspection PyPep8
+    ensureString = str
 else:
     ints2octs = bytes
+    # noinspection PyPep8
     int2oct = lambda x: ints2octs((x,))
     null = ints2octs()
+    # noinspection PyPep8
     oct2int = lambda x: x
-    octs2ints = lambda s: [ x for x in s ]
-    str2octs = lambda x: x.encode()
-    octs2str = lambda x: x.decode()
+    # noinspection PyPep8
+    octs2ints = lambda x: x
+    # noinspection PyPep8
+    str2octs = lambda x: x.encode('iso-8859-1')
+    # noinspection PyPep8
+    octs2str = lambda x: x.decode('iso-8859-1')
+    # noinspection PyPep8
     isOctetsType = lambda s: isinstance(s, bytes)
+    # noinspection PyPep8
+    isStringType = lambda s: isinstance(s, str)
+    # noinspection PyPep8
+    ensureString = bytes
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/pyasn1/compat/string.py
@@ -0,0 +1,26 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+from sys import version_info
+
+if version_info[:2] <= (2, 5):
+
+    def partition(string, sep):
+        try:
+            a, c = string.split(sep, 1)
+
+        except ValueError:
+            a, b, c = string, '', ''
+
+        else:
+            b = sep
+
+        return a, b, c
+
+else:
+
+    def partition(string, sep):
+        return string.partition(sep)
--- a/third_party/python/pyasn1/pyasn1/debug.py
+++ b/third_party/python/pyasn1/pyasn1/debug.py
@@ -1,65 +1,143 @@
-import sys
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import logging
 from pyasn1.compat.octets import octs2ints
 from pyasn1 import error
 from pyasn1 import __version__
 
-flagNone     = 0x0000
-flagEncoder  = 0x0001
-flagDecoder  = 0x0002
-flagAll      = 0xffff
+__all__ = ['Debug', 'setLogger', 'hexdump']
+
+flagNone = 0x0000
+flagEncoder = 0x0001
+flagDecoder = 0x0002
+flagAll = 0xffff
 
 flagMap = {
     'encoder': flagEncoder,
     'decoder': flagDecoder,
     'all': flagAll
-    }
+}
+
+
+class Printer(object):
+    # noinspection PyShadowingNames
+    def __init__(self, logger=None, handler=None, formatter=None):
+        if logger is None:
+            logger = logging.getLogger('pyasn1')
+
+        logger.setLevel(logging.DEBUG)
+
+        if handler is None:
+            handler = logging.StreamHandler()
+
+        if formatter is None:
+            formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s')
+
+        handler.setFormatter(formatter)
+        handler.setLevel(logging.DEBUG)
+        logger.addHandler(handler)
 
-class Debug:
-    defaultPrinter = sys.stderr.write
-    def __init__(self, *flags):
+        self.__logger = logger
+
+    def __call__(self, msg):
+        self.__logger.debug(msg)
+
+    def __str__(self):
+        return '<python logging>'
+
+
+if hasattr(logging, 'NullHandler'):
+    NullHandler = logging.NullHandler
+
+else:
+    # Python 2.6 and older
+    class NullHandler(logging.Handler):
+        def emit(self, record):
+            pass
+
+
+class Debug(object):
+    defaultPrinter = Printer()
+
+    def __init__(self, *flags, **options):
         self._flags = flagNone
-        self._printer = self.defaultPrinter
-        self('running pyasn1 version %s' % __version__)
-        for f in flags:
-            if f not in flagMap:
-                raise error.PyAsn1Error('bad debug flag %s' % (f,))
-            self._flags = self._flags | flagMap[f]
-            self('debug category \'%s\' enabled' % f)
-        
+
+        if 'loggerName' in options:
+            # route our logs to parent logger
+            self._printer = Printer(
+                logger=logging.getLogger(options['loggerName']),
+                handler=NullHandler()
+            )
+
+        elif 'printer' in options:
+            self._printer = options.get('printer')
+
+        else:
+            self._printer = self.defaultPrinter
+
+        self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags)))
+
+        for flag in flags:
+            inverse = flag and flag[0] in ('!', '~')
+            if inverse:
+                flag = flag[1:]
+            try:
+                if inverse:
+                    self._flags &= ~flagMap[flag]
+                else:
+                    self._flags |= flagMap[flag]
+            except KeyError:
+                raise error.PyAsn1Error('bad debug flag %s' % flag)
+
+            self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled'))
+
     def __str__(self):
         return 'logger %s, flags %x' % (self._printer, self._flags)
-    
+
     def __call__(self, msg):
-        self._printer('DBG: %s\n' % msg)
+        self._printer(msg)
 
     def __and__(self, flag):
         return self._flags & flag
 
     def __rand__(self, flag):
         return flag & self._flags
 
+
 logger = 0
 
-def setLogger(l):
+
+def setLogger(userLogger):
     global logger
-    logger = l
+
+    if userLogger:
+        logger = userLogger
+    else:
+        logger = 0
+
 
 def hexdump(octets):
     return ' '.join(
-            [ '%s%.2X' % (n%16 == 0 and ('\n%.5d: ' % n) or '', x) 
-              for n,x in zip(range(len(octets)), octs2ints(octets)) ]
-        )
+        ['%s%.2X' % (n % 16 == 0 and ('\n%.5d: ' % n) or '', x)
+         for n, x in zip(range(len(octets)), octs2ints(octets))]
+    )
 
-class Scope:
+
+class Scope(object):
     def __init__(self):
         self._list = []
 
     def __str__(self): return '.'.join(self._list)
 
     def push(self, token):
         self._list.append(token)
 
     def pop(self):
         return self._list.pop()
 
+
 scope = Scope()
--- a/third_party/python/pyasn1/pyasn1/error.py
+++ b/third_party/python/pyasn1/pyasn1/error.py
@@ -1,3 +1,18 @@
-class PyAsn1Error(Exception): pass
-class ValueConstraintError(PyAsn1Error): pass
-class SubstrateUnderrunError(PyAsn1Error): pass
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+
+
+class PyAsn1Error(Exception):
+    pass
+
+
+class ValueConstraintError(PyAsn1Error):
+    pass
+
+
+class SubstrateUnderrunError(PyAsn1Error):
+    pass
--- a/third_party/python/pyasn1/pyasn1/type/base.py
+++ b/third_party/python/pyasn1/pyasn1/type/base.py
@@ -1,139 +1,399 @@
-# Base classes for ASN.1 types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 import sys
-from pyasn1.type import constraint, tagmap
+from pyasn1.type import constraint, tagmap, tag
+from pyasn1.compat import calling
 from pyasn1 import error
 
-class Asn1Item: pass
+__all__ = ['Asn1Item', 'Asn1ItemBase', 'AbstractSimpleAsn1Item', 'AbstractConstructedAsn1Item']
+
+
+class Asn1Item(object):
+    @classmethod
+    def getTypeId(cls, increment=1):
+        try:
+            Asn1Item._typeCounter += increment
+        except AttributeError:
+            Asn1Item._typeCounter = increment
+        return Asn1Item._typeCounter
+
 
 class Asn1ItemBase(Asn1Item):
-    # Set of tags for this ASN.1 type
-    tagSet = ()
-    
-    # A list of constraint.Constraint instances for checking values
+    #: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing
+    #: ASN.1 tag(s) associated with |ASN.1| type.
+    tagSet = tag.TagSet()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing constraints on initialization values.
     subtypeSpec = constraint.ConstraintsIntersection()
 
-    # Used for ambiguous ASN.1 types identification
+    # Disambiguation ASN.1 types identification
     typeId = None
-    
-    def __init__(self, tagSet=None, subtypeSpec=None):
-        if tagSet is None:
-            self._tagSet = self.tagSet
-        else:
-            self._tagSet = tagSet
-        if subtypeSpec is None:
-            self._subtypeSpec = self.subtypeSpec
-        else:
-            self._subtypeSpec = subtypeSpec
+
+    def __init__(self, **kwargs):
+        readOnly = {
+            'tagSet': self.tagSet,
+            'subtypeSpec': self.subtypeSpec
+        }
+
+        readOnly.update(kwargs)
+
+        self.__dict__.update(readOnly)
+
+        self._readOnly = readOnly
+
+    def __setattr__(self, name, value):
+        if name[0] != '_' and name in self._readOnly:
+            raise error.PyAsn1Error('read-only instance attribute "%s"' % name)
+
+        self.__dict__[name] = value
+
+    @property
+    def readOnly(self):
+        return self._readOnly
+
+    @property
+    def effectiveTagSet(self):
+        """For |ASN.1| type is equivalent to *tagSet*
+        """
+        return self.tagSet  # used by untagged types
 
-    def _verifySubtypeSpec(self, value, idx=None):
-        try:
-            self._subtypeSpec(value, idx)
-        except error.PyAsn1Error:
-            c, i, t = sys.exc_info()
-            raise c('%s at %s' % (i, self.__class__.__name__))
+    @property
+    def tagMap(self):
+        """Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object.
+        """
+        return tagmap.TagMap({self.tagSet: self})
+
+    def isSameTypeWith(self, other, matchTags=True, matchConstraints=True):
+        """Examine |ASN.1| type for equality with other ASN.1 type.
+
+        ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
+        (:py:mod:`~pyasn1.type.constraint`) are examined when carrying
+        out ASN.1 types comparison.
+
+        No Python inheritance relationship between PyASN1 objects is considered.
+
+        Parameters
+        ----------
+        other: a pyasn1 type object
+            Class instance representing ASN.1 type.
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if *other* is |ASN.1| type,
+            :class:`False` otherwise.
+        """
+        return (self is other or
+                (not matchTags or self.tagSet == other.tagSet) and
+                (not matchConstraints or self.subtypeSpec == other.subtypeSpec))
+
+    def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True):
+        """Examine |ASN.1| type for subtype relationship with other ASN.1 type.
         
-    def getSubtypeSpec(self): return self._subtypeSpec
-    
-    def getTagSet(self): return self._tagSet
-    def getEffectiveTagSet(self): return self._tagSet  # used by untagged types
-    def getTagMap(self): return tagmap.TagMap({self._tagSet: self})
-    
-    def isSameTypeWith(self, other):
-        return self is other or \
-               self._tagSet == other.getTagSet() and \
-               self._subtypeSpec == other.getSubtypeSpec()
-    def isSuperTypeOf(self, other):
-        """Returns true if argument is a ASN1 subtype of ourselves"""
-        return self._tagSet.isSuperTagSetOf(other.getTagSet()) and \
-               self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec())
+        ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
+        (:py:mod:`~pyasn1.type.constraint`) are examined when carrying
+        out ASN.1 types comparison.
+
+        No Python inheritance relationship between PyASN1 objects is considered.
+
+
+        Parameters
+        ----------
+            other: a pyasn1 type object
+                Class instance representing ASN.1 type. 
+
+        Returns
+        -------
+            : :class:`bool`
+                :class:`True` if *other* is a subtype of |ASN.1| type,
+                :class:`False` otherwise.
+        """
+        return (not matchTags or
+                (self.tagSet.isSuperTagSetOf(other.tagSet)) and
+                 (not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec)))
+
+    @staticmethod
+    def isNoValue(*values):
+        for value in values:
+            if value is not None and value is not noValue:
+                return False
+        return True
+
+    # backward compatibility
+
+    def getTagSet(self):
+        return self.tagSet
+
+    def getEffectiveTagSet(self):
+        return self.effectiveTagSet
+
+    def getTagMap(self):
+        return self.tagMap
+
+    def getSubtypeSpec(self):
+        return self.subtypeSpec
+
+    def hasValue(self):
+        return self.isValue
+
 
-class __NoValue:
+class NoValue(object):
+    """Create a singleton instance of NoValue class.
+
+    NoValue object can be used as an initializer on PyASN1 type class
+    instantiation to represent ASN.1 type rather than ASN.1 data value.
+
+    No operations other than type comparison can be performed on
+    a PyASN1 type object.
+    """
+    skipMethods = ('__getattribute__', '__getattr__', '__setattr__', '__delattr__',
+                   '__class__', '__init__', '__del__', '__new__', '__repr__', 
+                   '__qualname__', '__objclass__', 'im_class', '__sizeof__')
+
+    _instance = None
+
+    def __new__(cls):
+        if cls._instance is None:
+            def getPlug(name):
+                def plug(self, *args, **kw):
+                    raise error.PyAsn1Error('Uninitialized ASN.1 value ("%s" attribute looked up)' % name)
+                return plug
+
+            op_names = [name
+                        for typ in (str, int, list, dict)
+                        for name in dir(typ)
+                        if (name not in cls.skipMethods and
+                            name.startswith('__') and
+                            name.endswith('__') and
+                            calling.callable(getattr(typ, name)))]
+
+            for name in set(op_names):
+                setattr(cls, name, getPlug(name))
+
+            cls._instance = object.__new__(cls)
+
+        return cls._instance
+
     def __getattr__(self, attr):
-        raise error.PyAsn1Error('No value for %s()' % attr)
-    def __getitem__(self, i):
-        raise error.PyAsn1Error('No value')
-    
-noValue = __NoValue()
+        if attr in self.skipMethods:
+            raise AttributeError('attribute %s not present' % attr)
+        raise error.PyAsn1Error('No value for "%s"' % attr)
+
+    def __repr__(self):
+        return '%s()' % self.__class__.__name__
+
+noValue = NoValue()
+
 
 # Base class for "simple" ASN.1 objects. These are immutable.
-class AbstractSimpleAsn1Item(Asn1ItemBase):    
+class AbstractSimpleAsn1Item(Asn1ItemBase):
+    #: Default payload value
     defaultValue = noValue
-    def __init__(self, value=None, tagSet=None, subtypeSpec=None):
-        Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
-        if value is None or value is noValue:
+
+    def __init__(self, value=noValue, **kwargs):
+        Asn1ItemBase.__init__(self, **kwargs)
+        if value is noValue or value is None:
             value = self.defaultValue
-        if value is None or value is noValue:
-            self.__hashedValue = value = noValue
         else:
             value = self.prettyIn(value)
-            self._verifySubtypeSpec(value)
-            self.__hashedValue = hash(value)
+            try:
+                self.subtypeSpec(value)
+
+            except error.PyAsn1Error:
+                exType, exValue, exTb = sys.exc_info()
+                raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
         self._value = value
-        self._len = None
-        
+
     def __repr__(self):
-        if self._value is noValue:
-            return self.__class__.__name__ + '()'
-        else:
-            return self.__class__.__name__ + '(%s)' % (self.prettyOut(self._value),)
-    def __str__(self): return str(self._value)
+        representation = []
+        if self._value is not self.defaultValue:
+            representation.append(self.prettyOut(self._value))
+        if self.tagSet is not self.__class__.tagSet:
+            representation.append('tagSet=%r' % (self.tagSet,))
+        if self.subtypeSpec is not self.__class__.subtypeSpec:
+            representation.append('subtypeSpec=%r' % (self.subtypeSpec,))
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(representation))
+
+    def __str__(self):
+        return str(self._value)
+
     def __eq__(self, other):
         return self is other and True or self._value == other
-    def __ne__(self, other): return self._value != other
-    def __lt__(self, other): return self._value < other
-    def __le__(self, other): return self._value <= other
-    def __gt__(self, other): return self._value > other
-    def __ge__(self, other): return self._value >= other
+
+    def __ne__(self, other):
+        return self._value != other
+
+    def __lt__(self, other):
+        return self._value < other
+
+    def __le__(self, other):
+        return self._value <= other
+
+    def __gt__(self, other):
+        return self._value > other
+
+    def __ge__(self, other):
+        return self._value >= other
+
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(self._value)
+        def __nonzero__(self):
+            return self._value and True or False
     else:
-        def __bool__(self): return bool(self._value)
-    def __hash__(self): return self.__hashedValue
+        def __bool__(self):
+            return self._value and True or False
+
+    def __hash__(self):
+        return hash(self._value)
+
+    @property
+    def isValue(self):
+        """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+        In other words, if *isValue* is `True`, then the ASN.1 object is
+        initialized.
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if object represents ASN.1 value and type,
+            :class:`False` if object represents just ASN.1 type.
+
+        Note
+        ----
+        There is an important distinction between PyASN1 type and value objects.
+        The PyASN1 type objects can only participate in ASN.1 type
+        operations (subtyping, comparison etc) and serve as a
+        blueprint for serialization codecs to resolve ambiguous types.
 
-    def clone(self, value=None, tagSet=None, subtypeSpec=None):
-        if value is None and tagSet is None and subtypeSpec is None:
-            return self
-        if value is None:
+        The PyASN1 value objects can additionally participate in most
+        of built-in Python operations.
+        """
+        return self._value is not noValue
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+          Any parameters to the *clone()* method will replace corresponding
+          properties of the |ASN.1| object.
+
+          Parameters
+          ----------
+          value: :class:`tuple`, :class:`str` or |ASN.1| object
+              Initialization value to pass to new ASN.1 object instead of
+              inheriting one from the caller.
+
+          tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+              Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+          subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+              Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+          Returns
+          -------
+          :
+              new instance of |ASN.1| type/value
+        """
+        if value is noValue or value is None:
+            if not kwargs:
+                return self
+
             value = self._value
-        if tagSet is None:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        return self.__class__(value, tagSet, subtypeSpec)
+
+        initilaizers = self.readOnly.copy()
+        initilaizers.update(kwargs)
+
+        return self.__class__(value, **initilaizers)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+         Any parameters to the *subtype()* method will be added to the corresponding
+         properties of the |ASN.1| object.
+
+         Parameters
+         ----------
+         value: :class:`tuple`, :class:`str` or |ASN.1| object
+             Initialization value to pass to new ASN.1 object instead of
+             inheriting one from the caller.
+
+         implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+             Implicitly apply given ASN.1 tag object to caller's
+             :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+             new object's ASN.1 tag(s).
 
-    def subtype(self, value=None, implicitTag=None, explicitTag=None,
-                subtypeSpec=None):
-        if value is None:
+         explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+             Explicitly apply given ASN.1 tag object to caller's
+             :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+             new object's ASN.1 tag(s).
+
+         subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+             Add ASN.1 constraints object to one of the caller, then
+             use the result as new object's ASN.1 constraints.
+
+         Returns
+         -------
+         :
+             new instance of |ASN.1| type/value
+        """
+        if value is noValue or value is None:
+            if not kwargs:
+                return self
+
             value = self._value
+
+        initializers = self.readOnly.copy()
+
+        implicitTag = kwargs.pop('implicitTag', None)
         if implicitTag is not None:
-            tagSet = self._tagSet.tagImplicitly(implicitTag)
-        elif explicitTag is not None:
-            tagSet = self._tagSet.tagExplicitly(explicitTag)
-        else:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        else:
-            subtypeSpec = subtypeSpec + self._subtypeSpec
-        return self.__class__(value, tagSet, subtypeSpec)
+            initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
+
+        explicitTag = kwargs.pop('explicitTag', None)
+        if explicitTag is not None:
+            initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
 
-    def prettyIn(self, value): return value
-    def prettyOut(self, value): return str(value)
+        for arg, option in kwargs.items():
+            initializers[arg] += option
+
+        return self.__class__(value, **initializers)
+
+    def prettyIn(self, value):
+        return value
+
+    def prettyOut(self, value):
+        return str(value)
 
     def prettyPrint(self, scope=0):
-        if self._value is noValue:
+        """Provide human-friendly printable object representation.
+
+        Returns
+        -------
+        : :class:`str`
+            human-friendly type and/or value representation.
+        """
+        if self.isValue:
+            return self.prettyOut(self._value)
+        else:
             return '<no value>'
-        else:
-            return self.prettyOut(self._value)
 
     # XXX Compatibility stub
-    def prettyPrinter(self, scope=0): return self.prettyPrint(scope)
-    
+    def prettyPrinter(self, scope=0):
+        return self.prettyPrint(scope)
+
+    # noinspection PyUnusedLocal
+    def prettyPrintType(self, scope=0):
+        return '%s -> %s' % (self.tagSet, self.__class__.__name__)
+
 #
 # Constructed types:
 # * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
 # * ASN1 types and values are represened by Python class instances
 # * Value initialization is made for defaulted components only
 # * Primary method of component addressing is by-position. Data model for base
 #   type is Python sequence. Additional type-specific addressing methods
 #   may be implemented for particular types.
@@ -143,107 +403,199 @@ class AbstractSimpleAsn1Item(Asn1ItemBas
 # * Sequence and Set types may include optional and defaulted
 #   components
 # * Constructed types hold a reference to component types used for value
 #   verification and ordering.
 # * Component type is a scalar type for SequenceOf/SetOf types and a list
 #   of types for Sequence/Set/Choice.
 #
 
+def setupComponent():
+    """Returns a sentinel value.
+
+     Indicates to a constructed type to set up its inner component so that it
+     can be referred to. This is useful in situation when you want to populate
+     descendants of a constructed type what requires being able to refer to
+     their parent types along the way.
+
+     Example
+     -------
+
+     >>> constructed['record'] = setupComponent()
+     >>> constructed['record']['scalar'] = 42
+    """
+    return noValue
+
+
 class AbstractConstructedAsn1Item(Asn1ItemBase):
+
+    #: If `True`, requires exact component type matching,
+    #: otherwise subtype relation is only enforced
+    strictConstraints = False
+
     componentType = None
-    sizeSpec = constraint.ConstraintsIntersection()
-    def __init__(self, componentType=None, tagSet=None,
-                 subtypeSpec=None, sizeSpec=None):
-        Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
-        if componentType is None:
-            self._componentType = self.componentType
-        else:
-            self._componentType = componentType
-        if sizeSpec is None:
-            self._sizeSpec = self.sizeSpec
-        else:
-            self._sizeSpec = sizeSpec
+    sizeSpec = None
+
+    def __init__(self, **kwargs):
+        readOnly = {
+            'componentType': self.componentType,
+            'sizeSpec': self.sizeSpec
+        }
+        readOnly.update(kwargs)
+
+        Asn1ItemBase.__init__(self, **readOnly)
+
         self._componentValues = []
-        self._componentValuesSet = 0
 
     def __repr__(self):
-        r = self.__class__.__name__ + '()'
-        for idx in range(len(self._componentValues)):
-            if self._componentValues[idx] is None:
-                continue
-            r = r + '.setComponentByPosition(%s, %r)' % (
-                idx, self._componentValues[idx]
-                )
-        return r
+        representation = []
+        if self.componentType is not self.__class__.componentType:
+            representation.append('componentType=%r' % (self.componentType,))
+        if self.tagSet is not self.__class__.tagSet:
+            representation.append('tagSet=%r' % (self.tagSet,))
+        if self.subtypeSpec is not self.__class__.subtypeSpec:
+            representation.append('subtypeSpec=%r' % (self.subtypeSpec,))
+        representation = '%s(%s)' % (self.__class__.__name__, ', '.join(representation))
+        if self._componentValues:
+            for idx, component in enumerate(self._componentValues):
+                if component is None or component is noValue:
+                    continue
+                representation += '.setComponentByPosition(%d, %s)' % (idx, repr(component))
+        return representation
 
     def __eq__(self, other):
         return self is other and True or self._componentValues == other
-    def __ne__(self, other): return self._componentValues != other
-    def __lt__(self, other): return self._componentValues < other
-    def __le__(self, other): return self._componentValues <= other
-    def __gt__(self, other): return self._componentValues > other
-    def __ge__(self, other): return self._componentValues >= other
+
+    def __ne__(self, other):
+        return self._componentValues != other
+
+    def __lt__(self, other):
+        return self._componentValues < other
+
+    def __le__(self, other):
+        return self._componentValues <= other
+
+    def __gt__(self, other):
+        return self._componentValues > other
+
+    def __ge__(self, other):
+        return self._componentValues >= other
+
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(self._componentValues)
+        def __nonzero__(self):
+            return self._componentValues and True or False
     else:
-        def __bool__(self): return bool(self._componentValues)
+        def __bool__(self):
+            return self._componentValues and True or False
+
+    def _cloneComponentValues(self, myClone, cloneValueFlag):
+        pass
 
-    def getComponentTagMap(self):
-        raise error.PyAsn1Error('Method not implemented')
+    def clone(self, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
 
-    def _cloneComponentValues(self, myClone, cloneValueFlag): pass
+        Parameters
+        ----------
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing non-default ASN.1 tag(s)
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 subtype constraint(s)
 
-    def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None, 
-              cloneValueFlag=None):
-        if tagSet is None:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        if sizeSpec is None:
-            sizeSpec = self._sizeSpec
-        r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
+        sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 size constraint(s)
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+
+        """
+        cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+        initilaizers = self.readOnly.copy()
+        initilaizers.update(kwargs)
+
+        clone = self.__class__(**initilaizers)
+
         if cloneValueFlag:
-            self._cloneComponentValues(r, cloneValueFlag)
-        return r
+            self._cloneComponentValues(clone, cloneValueFlag)
+
+        return clone
+
+    def subtype(self, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing non-default ASN.1 tag(s)
 
-    def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None,
-                sizeSpec=None, cloneValueFlag=None):
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 subtype constraint(s)
+
+        sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 size constraint(s)
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+
+        """
+
+        initializers = self.readOnly.copy()
+
+        cloneValueFlag = kwargs.pop('cloneValueFlag', False)
+
+        implicitTag = kwargs.pop('implicitTag', None)
         if implicitTag is not None:
-            tagSet = self._tagSet.tagImplicitly(implicitTag)
-        elif explicitTag is not None:
-            tagSet = self._tagSet.tagExplicitly(explicitTag)
-        else:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        else:
-            subtypeSpec = subtypeSpec + self._subtypeSpec
-        if sizeSpec is None:
-            sizeSpec = self._sizeSpec
-        else:
-            sizeSpec = sizeSpec + self._sizeSpec
-        r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
+            initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
+
+        explicitTag = kwargs.pop('explicitTag', None)
+        if explicitTag is not None:
+            initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
+
+        for arg, option in kwargs.items():
+            initializers[arg] += option
+
+        clone = self.__class__(**initializers)
+
         if cloneValueFlag:
-            self._cloneComponentValues(r, cloneValueFlag)
-        return r
+            self._cloneComponentValues(clone, cloneValueFlag)
 
-    def _verifyComponent(self, idx, value): pass
+        return clone
 
-    def verifySizeSpec(self): self._sizeSpec(self)
+    def verifySizeSpec(self):
+        self.sizeSpec(self)
 
     def getComponentByPosition(self, idx):
         raise error.PyAsn1Error('Method not implemented')
+
     def setComponentByPosition(self, idx, value, verifyConstraints=True):
         raise error.PyAsn1Error('Method not implemented')
 
-    def getComponentType(self): return self._componentType
+    def setComponents(self, *args, **kwargs):
+        for idx, value in enumerate(args):
+            self[idx] = value
+        for k in kwargs:
+            self[k] = kwargs[k]
+        return self
 
-    def __getitem__(self, idx): return self.getComponentByPosition(idx)
-    def __setitem__(self, idx, value): self.setComponentByPosition(idx, value)
+    def __len__(self):
+        return len(self._componentValues)
 
-    def __len__(self): return len(self._componentValues)
-    
     def clear(self):
         self._componentValues = []
-        self._componentValuesSet = 0
+
+    # backward compatibility
 
-    def setDefaultComponents(self): pass
+    def setDefaultComponents(self):
+        pass
+
+    def getComponentType(self):
+        return self.componentType
--- a/third_party/python/pyasn1/pyasn1/type/char.py
+++ b/third_party/python/pyasn1/pyasn1/type/char.py
@@ -1,61 +1,374 @@
-# ASN.1 "character string" types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
 from pyasn1.type import univ, tag
+from pyasn1 import error
+
+
+__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString',
+           'IA5String', 'GraphicString', 'VisibleString', 'ISO646String',
+           'GeneralString', 'UniversalString', 'BMPString', 'UTF8String']
+
+NoValue = univ.NoValue
+noValue = univ.noValue
+
+
+class AbstractCharacterString(univ.OctetString):
+    """Creates |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python 2 :class:`unicode` or Python 3 :class:`str`.
+    When used in octet-stream context, |ASN.1| type assumes "|encoding|" encoding.
+
+    Parameters
+    ----------
+    value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+        unicode object (Python 2) or string (Python 3), alternatively string
+        (Python 2) or bytes (Python 3) representing octet-stream of serialized
+        unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    encoding: :py:class:`str`
+        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
+        :class:`str` (Python 3) the payload when |ASN.1| object is used
+        in octet-stream context.
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
+
+    if sys.version_info[0] <= 2:
+        def __str__(self):
+            try:
+                return self._value.encode(self.encoding)
+            except UnicodeEncodeError:
+                raise error.PyAsn1Error(
+                    "Can't encode string '%s' with codec %s" % (self._value, self.encoding)
+                )
+
+        def __unicode__(self):
+            return unicode(self._value)
+
+        def prettyIn(self, value):
+            try:
+                if isinstance(value, unicode):
+                    return value
+                elif isinstance(value, str):
+                    return value.decode(self.encoding)
+                elif isinstance(value, (tuple, list)):
+                    return self.prettyIn(''.join([chr(x) for x in value]))
+                elif isinstance(value, univ.OctetString):
+                    return value.asOctets().decode(self.encoding)
+                else:
+                    return unicode(value)
+
+            except (UnicodeDecodeError, LookupError):
+                raise error.PyAsn1Error(
+                    "Can't decode string '%s' with codec %s" % (value, self.encoding)
+                )
+
+        def asOctets(self, padding=True):
+            return str(self)
+
+        def asNumbers(self, padding=True):
+            return tuple([ord(x) for x in str(self)])
+
+    else:
+        def __str__(self):
+            return str(self._value)
+
+        def __bytes__(self):
+            try:
+                return self._value.encode(self.encoding)
+            except UnicodeEncodeError:
+                raise error.PyAsn1Error(
+                    "Can't encode string '%s' with codec %s" % (self._value, self.encoding)
+                )
+
+        def prettyIn(self, value):
+            try:
+                if isinstance(value, str):
+                    return value
+                elif isinstance(value, bytes):
+                    return value.decode(self.encoding)
+                elif isinstance(value, (tuple, list)):
+                    return self.prettyIn(bytes(value))
+                elif isinstance(value, univ.OctetString):
+                    return value.asOctets().decode(self.encoding)
+                else:
+                    return str(value)
+
+            except (UnicodeDecodeError, LookupError):
+                raise error.PyAsn1Error(
+                    "Can't decode string '%s' with codec %s" % (value, self.encoding)
+                )
+
+        def asOctets(self, padding=True):
+            return bytes(self)
+
+        def asNumbers(self, padding=True):
+            return tuple(bytes(self))
+
+    def prettyOut(self, value):
+        return value
+
+    def __reversed__(self):
+        return reversed(self._value)
+
+    def clone(self, value=noValue, **kwargs):
+        """Creates a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+            unicode object (Python 2) or string (Python 3), alternatively string
+            (Python 2) or bytes (Python 3) representing octet-stream of serialized
+            unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing non-default ASN.1 tag(s)
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 subtype constraint(s)
+
+        encoding: :py:class:`str`
+            Unicode codec ID to encode/decode :py:class:`unicode` (Python 2) or
+            :py:class:`str` (Python 3) the payload when |ASN.1| object is used
+            in octet-stream context.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+
+        """
+        return univ.OctetString.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Creates a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
+            unicode object (Python 2) or string (Python 3), alternatively string
+            (Python 2) or bytes (Python 3) representing octet-stream of serialized
+            unicode string (note `encoding` parameter) or |ASN.1| class instance.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to caller's
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to caller's
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing non-default ASN.1 subtype constraint(s)
 
-class UTF8String(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
+        encoding: :py:class:`str`
+            Unicode codec ID to encode/decode :py:class:`unicode` (Python 2) or
+            :py:class:`str` (Python 3) the payload when |ASN.1| object is used
+            in octet-stream context.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+
+        """
+        return univ.OctetString.subtype(self, value, **kwargs)
+
+class NumericString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
+    )
+    encoding = 'us-ascii'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class PrintableString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
+    )
+    encoding = 'us-ascii'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class TeletexString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
+    )
+    encoding = 'iso-8859-1'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class T61String(TeletexString):
+    __doc__ = TeletexString.__doc__
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class VideotexString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
+    )
+    encoding = 'iso-8859-1'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class IA5String(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
+    )
+    encoding = 'us-ascii'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class GraphicString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
+    )
+    encoding = 'iso-8859-1'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class VisibleString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
+    )
+    encoding = 'us-ascii'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class ISO646String(VisibleString):
+    __doc__ = VisibleString.__doc__
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+class GeneralString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
+    )
+    encoding = 'iso-8859-1'
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class UniversalString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
+    )
+    encoding = "utf-32-be"
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class BMPString(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
+    )
+    encoding = "utf-16-be"
+
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
+
+
+class UTF8String(AbstractCharacterString):
+    __doc__ = AbstractCharacterString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = AbstractCharacterString.tagSet.tagImplicitly(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
-        )
+    )
     encoding = "utf-8"
 
-class NumericString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
-        )
-
-class PrintableString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
-        )
-
-class TeletexString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
-        )
-    
-
-class VideotexString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
-        )
-
-class IA5String(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
-        )
-
-class GraphicString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
-        )
-
-class VisibleString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
-        )
-
-class GeneralString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
-        )
-
-class UniversalString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
-        )
-    encoding = "utf-32-be"
-
-class BMPString(univ.OctetString):
-    tagSet = univ.OctetString.tagSet.tagImplicitly(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
-        )
-    encoding = "utf-16-be"
+    # Optimization for faster codec lookup
+    typeId = AbstractCharacterString.getTypeId()
--- a/third_party/python/pyasn1/pyasn1/type/constraint.py
+++ b/third_party/python/pyasn1/pyasn1/type/constraint.py
@@ -1,200 +1,258 @@
 #
-#   ASN.1 subtype constraints classes.
+# This file is part of pyasn1 software.
 #
-#   Constraints are relatively rare, but every ASN1 object
-#   is doing checks all the time for whether they have any
-#   constraints and whether they are applicable to the object.
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
 #
-#   What we're going to do is define objects/functions that
-#   can be called unconditionally if they are present, and that
-#   are simply not present if there are no constraints.
-#
-#   Original concept and code by Mike C. Fletcher.
+# Original concept and code by Mike C. Fletcher.
 #
 import sys
 from pyasn1.type import error
 
-class AbstractConstraint:
+__all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint', 'ValueRangeConstraint',
+           'ValueSizeConstraint', 'PermittedAlphabetConstraint', 'InnerTypeConstraint',
+           'ConstraintsExclusion', 'ConstraintsIntersection', 'ConstraintsUnion']
+
+
+class AbstractConstraint(object):
     """Abstract base-class for constraint objects
 
        Constraints should be stored in a simple sequence in the
-       namespace of their client Asn1Item sub-classes.
+       namespace of their client Asn1Item sub-classes in cases
+       when ASN.1 constraint is define.
     """
+
     def __init__(self, *values):
-        self._valueMap = {}
+        self._valueMap = set()
         self._setValues(values)
-        self.__hashedValues = None
+        self.__hash = hash((self.__class__.__name__, self._values))
+
     def __call__(self, value, idx=None):
+        if not self._values:
+            return
+
         try:
             self._testValue(value, idx)
+
         except error.ValueConstraintError:
             raise error.ValueConstraintError(
-               '%s failed at: \"%s\"' % (self, sys.exc_info()[1])
+                '%s failed at: %r' % (self, sys.exc_info()[1])
             )
+
     def __repr__(self):
         return '%s(%s)' % (
             self.__class__.__name__,
             ', '.join([repr(x) for x in self._values])
         )
+
     def __eq__(self, other):
         return self is other and True or self._values == other
-    def __ne__(self, other): return self._values != other
-    def __lt__(self, other): return self._values < other
-    def __le__(self, other): return self._values <= other
-    def __gt__(self, other): return self._values > other
-    def __ge__(self, other): return self._values >= other
+
+    def __ne__(self, other):
+        return self._values != other
+
+    def __lt__(self, other):
+        return self._values < other
+
+    def __le__(self, other):
+        return self._values <= other
+
+    def __gt__(self, other):
+        return self._values > other
+
+    def __ge__(self, other):
+        return self._values >= other
+
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(self._values)
+        def __nonzero__(self):
+            return self._values and True or False
     else:
-        def __bool__(self): return bool(self._values)
+        def __bool__(self):
+            return self._values and True or False
 
     def __hash__(self):
-        if self.__hashedValues is None:
-            self.__hashedValues = hash((self.__class__.__name__, self._values))
-        return self.__hashedValues
+        return self.__hash
 
-    def _setValues(self, values): self._values = values
+    def _setValues(self, values):
+        self._values = values
+
     def _testValue(self, value, idx):
         raise error.ValueConstraintError(value)
 
     # Constraints derivation logic
-    def getValueMap(self): return self._valueMap
+    def getValueMap(self):
+        return self._valueMap
+
     def isSuperTypeOf(self, otherConstraint):
-        return self in otherConstraint.getValueMap() or \
-               otherConstraint is self or otherConstraint == self
+        # TODO: fix possible comparison of set vs scalars here
+        return (otherConstraint is self or
+                not self._values or
+                otherConstraint == self or
+                self in otherConstraint.getValueMap())
+
     def isSubTypeOf(self, otherConstraint):
-        return otherConstraint in self._valueMap or \
-               otherConstraint is self or otherConstraint == self
+        return (otherConstraint is self or
+                not self or
+                otherConstraint == self or
+                otherConstraint in self._valueMap)
 
 class SingleValueConstraint(AbstractConstraint):
     """Value must be part of defined values constraint"""
+
+    def _setValues(self, values):
+        self._values = values
+        self._set = set(values)
+
     def _testValue(self, value, idx):
-        # XXX index vals for performance?
-        if value not in self._values:
+        if value not in self._set:
             raise error.ValueConstraintError(value)
 
+
 class ContainedSubtypeConstraint(AbstractConstraint):
     """Value must satisfy all of defined set of constraints"""
+
     def _testValue(self, value, idx):
         for c in self._values:
             c(value, idx)
 
+
 class ValueRangeConstraint(AbstractConstraint):
     """Value must be within start and stop values (inclusive)"""
+
     def _testValue(self, value, idx):
         if value < self.start or value > self.stop:
             raise error.ValueConstraintError(value)
 
     def _setValues(self, values):
         if len(values) != 2:
             raise error.PyAsn1Error(
                 '%s: bad constraint values' % (self.__class__.__name__,)
-                )
+            )
         self.start, self.stop = values
         if self.start > self.stop:
             raise error.PyAsn1Error(
                 '%s: screwed constraint values (start > stop): %s > %s' % (
                     self.__class__.__name__,
                     self.start, self.stop
                 )
             )
         AbstractConstraint._setValues(self, values)
-        
+
+
 class ValueSizeConstraint(ValueRangeConstraint):
     """len(value) must be within start and stop values (inclusive)"""
+
     def _testValue(self, value, idx):
-        l = len(value)
-        if l < self.start or l > self.stop:
+        valueSize = len(value)
+        if valueSize < self.start or valueSize > self.stop:
             raise error.ValueConstraintError(value)
 
+
 class PermittedAlphabetConstraint(SingleValueConstraint):
     def _setValues(self, values):
-        self._values = ()
-        for v in values:
-            self._values = self._values + tuple(v)
+        self._values = values
+        self._set = set(values)
 
     def _testValue(self, value, idx):
-        for v in value:
-            if v not in self._values:
-                raise error.ValueConstraintError(value)
+        if not self._set.issuperset(value):
+            raise error.ValueConstraintError(value)
 
-# This is a bit kludgy, meaning two op modes within a single constraing
+
+# This is a bit kludgy, meaning two op modes within a single constraint
 class InnerTypeConstraint(AbstractConstraint):
     """Value must satisfy type and presense constraints"""
+
     def _testValue(self, value, idx):
         if self.__singleTypeConstraint:
             self.__singleTypeConstraint(value)
         elif self.__multipleTypeConstraint:
             if idx not in self.__multipleTypeConstraint:
                 raise error.ValueConstraintError(value)
             constraint, status = self.__multipleTypeConstraint[idx]
-            if status == 'ABSENT':   # XXX presense is not checked!
+            if status == 'ABSENT':  # XXX presense is not checked!
                 raise error.ValueConstraintError(value)
             constraint(value)
 
     def _setValues(self, values):
         self.__multipleTypeConstraint = {}
         self.__singleTypeConstraint = None
         for v in values:
             if isinstance(v, tuple):
                 self.__multipleTypeConstraint[v[0]] = v[1], v[2]
             else:
                 self.__singleTypeConstraint = v
         AbstractConstraint._setValues(self, values)
 
-# Boolean ops on constraints 
+
+# Boolean ops on constraints
 
 class ConstraintsExclusion(AbstractConstraint):
     """Value must not fit the single constraint"""
+
     def _testValue(self, value, idx):
         try:
             self._values[0](value, idx)
         except error.ValueConstraintError:
             return
         else:
             raise error.ValueConstraintError(value)
 
     def _setValues(self, values):
         if len(values) != 1:
             raise error.PyAsn1Error('Single constraint expected')
         AbstractConstraint._setValues(self, values)
 
+
 class AbstractConstraintSet(AbstractConstraint):
     """Value must not satisfy the single constraint"""
-    def __getitem__(self, idx): return self._values[idx]
+
+    def __getitem__(self, idx):
+        return self._values[idx]
+
+    def __iter__(self):
+        return iter(self._values)
 
-    def __add__(self, value): return self.__class__(self, value)
-    def __radd__(self, value): return self.__class__(self, value)
+    def __add__(self, value):
+        return self.__class__(*(self._values + (value,)))
 
-    def __len__(self): return len(self._values)
+    def __radd__(self, value):
+        return self.__class__(*((value,) + self._values))
+
+    def __len__(self):
+        return len(self._values)
 
     # Constraints inclusion in sets
-    
+
     def _setValues(self, values):
         self._values = values
-        for v in values:
-            self._valueMap[v] = 1
-            self._valueMap.update(v.getValueMap())
+        for constraint in values:
+            if constraint:
+                self._valueMap.add(constraint)
+                self._valueMap.update(constraint.getValueMap())
+
 
 class ConstraintsIntersection(AbstractConstraintSet):
     """Value must satisfy all constraints"""
+
     def _testValue(self, value, idx):
-        for v in self._values:
-            v(value, idx)
+        for constraint in self._values:
+            constraint(value, idx)
+
 
 class ConstraintsUnion(AbstractConstraintSet):
     """Value must satisfy at least one constraint"""
+
     def _testValue(self, value, idx):
-        for v in self._values:
+        for constraint in self._values:
             try:
-                v(value, idx)
+                constraint(value, idx)
             except error.ValueConstraintError:
                 pass
             else:
                 return
         raise error.ValueConstraintError(
             'all of %s failed for \"%s\"' % (self._values, value)
-            )
+        )
 
 # XXX
 # add tests for type check
--- a/third_party/python/pyasn1/pyasn1/type/error.py
+++ b/third_party/python/pyasn1/pyasn1/type/error.py
@@ -1,3 +1,11 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1.error import PyAsn1Error
 
-class ValueConstraintError(PyAsn1Error): pass
+
+class ValueConstraintError(PyAsn1Error):
+    pass
--- a/third_party/python/pyasn1/pyasn1/type/namedtype.py
+++ b/third_party/python/pyasn1/pyasn1/type/namedtype.py
@@ -1,132 +1,511 @@
-# NamedType specification for constructed types
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 import sys
-from pyasn1.type import tagmap
+from pyasn1.type import tag, tagmap
 from pyasn1 import error
 
-class NamedType:
-    isOptional = 0
-    isDefaulted = 0
-    def __init__(self, name, t):
-        self.__name = name; self.__type = t
-    def __repr__(self): return '%s(%s, %s)' % (
-        self.__class__.__name__, self.__name, self.__type
-        )
-    def getType(self): return self.__type
-    def getName(self): return self.__name
+__all__ = ['NamedType', 'OptionalNamedType', 'DefaultedNamedType', 'NamedTypes']
+
+
+class NamedType(object):
+    """Create named field object for a constructed ASN.1 type.
+
+    The |NamedType| object represents a single name and ASN.1 type of a constructed ASN.1 type.
+
+    |NamedType| objects are immutable and duck-type Python :class:`tuple` objects
+    holding *name* and *asn1Object* components.
+
+    Parameters
+    ----------
+    name: :py:class:`str`
+        Field name
+
+    asn1Object:
+        ASN.1 type object
+    """
+    isOptional = False
+    isDefaulted = False
+
+    def __init__(self, name, asn1Object):
+        self.__name = name
+        self.__type = asn1Object
+        self.__nameAndType = name, asn1Object
+
+    def __repr__(self):
+        return '%s(%r, %r)' % (self.__class__.__name__, self.__name, self.__type)
+
+    def __eq__(self, other):
+        return self.__nameAndType == other
+
+    def __ne__(self, other):
+        return self.__nameAndType != other
+
+    def __lt__(self, other):
+        return self.__nameAndType < other
+
+    def __le__(self, other):
+        return self.__nameAndType <= other
+
+    def __gt__(self, other):
+        return self.__nameAndType > other
+
+    def __ge__(self, other):
+        return self.__nameAndType >= other
+
+    def __hash__(self):
+        return hash(self.__nameAndType)
+
     def __getitem__(self, idx):
-        if idx == 0: return self.__name
-        if idx == 1: return self.__type
-        raise IndexError()
+        return self.__nameAndType[idx]
+
+    def __iter__(self):
+        return iter(self.__nameAndType)
+
+    @property
+    def name(self):
+        return self.__name
     
+    @property
+    def asn1Object(self):
+        return self.__type
+
+    # Backward compatibility
+
+    def getName(self):
+        return self.name
+
+    def getType(self):
+        return self.asn1Object
+
+
 class OptionalNamedType(NamedType):
-    isOptional = 1
+    __doc__ = NamedType.__doc__
+
+    isOptional = True
+
+
 class DefaultedNamedType(NamedType):
-    isDefaulted = 1
-    
-class NamedTypes:
-    def __init__(self, *namedTypes):
+    __doc__ = NamedType.__doc__
+
+    isDefaulted = True
+
+
+class NamedTypes(object):
+    """Create a collection of named fields for a constructed ASN.1 type.
+
+    The NamedTypes object represents a collection of named fields of a constructed ASN.1 type.
+
+    *NamedTypes* objects are immutable and duck-type Python :class:`dict` objects
+    holding *name* as keys and ASN.1 type object as values.
+
+    Parameters
+    ----------
+    *namedTypes: :class:`~pyasn1.type.namedtype.NamedType`
+    """
+    def __init__(self, *namedTypes, **kwargs):
         self.__namedTypes = namedTypes
         self.__namedTypesLen = len(self.__namedTypes)
-        self.__minTagSet = None
-        self.__tagToPosIdx = {}; self.__nameToPosIdx = {}
-        self.__tagMap = { False: None, True: None }
-        self.__ambigiousTypes = {}
+        self.__minTagSet = self.__computeMinTagSet()
+        self.__nameToPosMap = self.__computeNameToPosMap()
+        self.__tagToPosMap = self.__computeTagToPosMap()
+        self.__ambiguousTypes = 'terminal' not in kwargs and self.__computeAmbiguousTypes() or {}
+        self.__uniqueTagMap = self.__computeTagMaps(unique=True)
+        self.__nonUniqueTagMap = self.__computeTagMaps(unique=False)
+        self.__hasOptionalOrDefault = bool([True for namedType in self.__namedTypes
+                                            if namedType.isDefaulted or namedType.isOptional])
+        self.__requiredComponents = frozenset(
+                [idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted]
+            )
+        self.__keys = frozenset([namedType.name for namedType in self.__namedTypes])
+        self.__values = tuple([namedType.asn1Object for namedType in self.__namedTypes])
+        self.__items = tuple([(namedType.name, namedType.asn1Object) for namedType in self.__namedTypes])
 
     def __repr__(self):
-        r = '%s(' % self.__class__.__name__
-        for n in self.__namedTypes:
-            r = r + '%r, ' % (n,)
-        return r + ')'
-    
-    def __getitem__(self, idx): return self.__namedTypes[idx]
+        return '%s(%s)' % (
+            self.__class__.__name__, ', '.join([repr(x) for x in self.__namedTypes])
+        )
+
+    def __eq__(self, other):
+        return self.__namedTypes == other
+
+    def __ne__(self, other):
+        return self.__namedTypes != other
+
+    def __lt__(self, other):
+        return self.__namedTypes < other
+
+    def __le__(self, other):
+        return self.__namedTypes <= other
+
+    def __gt__(self, other):
+        return self.__namedTypes > other
+
+    def __ge__(self, other):
+        return self.__namedTypes >= other
+
+    def __hash__(self):
+        return hash(self.__namedTypes)
+
+    def __getitem__(self, idx):
+        try:
+            return self.__namedTypes[idx]
+
+        except TypeError:
+            return self.__namedTypes[self.__nameToPosMap[idx]]
+
+    def __contains__(self, key):
+        return key in self.__nameToPosMap
+
+    def __iter__(self):
+        return (x[0] for x in self.__namedTypes)
 
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(self.__namedTypesLen)
+        def __nonzero__(self):
+            return self.__namedTypesLen > 0
     else:
-        def __bool__(self): return bool(self.__namedTypesLen)
-    def __len__(self): return self.__namedTypesLen
-    
+        def __bool__(self):
+            return self.__namedTypesLen > 0
+
+    def __len__(self):
+        return self.__namedTypesLen
+
+    # Python dict protocol
+
+    def values(self):
+        return self.__values
+
+    def keys(self):
+        return self.__keys
+
+    def items(self):
+        return self.__items
+
+    def clone(self):
+        return self.__class__(*self.__namedTypes)
+
+    class PostponedError(object):
+        def __init__(self, errorMsg):
+            self.__errorMsg = errorMsg
+
+        def __getitem__(self, item):
+            raise  error.PyAsn1Error(self.__errorMsg)
+
+    def __computeTagToPosMap(self):
+        tagToPosMap = {}
+        for idx, namedType in enumerate(self.__namedTypes):
+            tagMap = namedType.asn1Object.tagMap
+            if isinstance(tagMap, NamedTypes.PostponedError):
+                return tagMap
+            if not tagMap:
+                continue
+            for _tagSet in tagMap.presentTypes:
+                if _tagSet in tagToPosMap:
+                    return NamedTypes.PostponedError('Duplicate component tag %s at %s' % (_tagSet, namedType))
+                tagToPosMap[_tagSet] = idx
+
+        return tagToPosMap
+
+    def __computeNameToPosMap(self):
+        nameToPosMap = {}
+        for idx, namedType in enumerate(self.__namedTypes):
+            if namedType.name in nameToPosMap:
+                return NamedTypes.PostponedError('Duplicate component name %s at %s' % (namedType.name, namedType))
+            nameToPosMap[namedType.name] = idx
+
+        return nameToPosMap
+
+    def __computeAmbiguousTypes(self):
+        ambigiousTypes = {}
+        partialAmbigiousTypes = ()
+        for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))):
+            if namedType.isOptional or namedType.isDefaulted:
+                partialAmbigiousTypes = (namedType,) + partialAmbigiousTypes
+            else:
+                partialAmbigiousTypes = (namedType,)
+            if len(partialAmbigiousTypes) == len(self.__namedTypes):
+                ambigiousTypes[idx] = self
+            else:
+                ambigiousTypes[idx] = NamedTypes(*partialAmbigiousTypes, **dict(terminal=True))
+        return ambigiousTypes
+
     def getTypeByPosition(self, idx):
-        if idx < 0 or idx >= self.__namedTypesLen:
+        """Return ASN.1 type object by its position in fields set.
+
+        Parameters
+        ----------
+        idx: :py:class:`int`
+            Field index
+
+        Returns
+        -------
+        :
+            ASN.1 type
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If given position is out of fields range
+        """
+        try:
+            return self.__namedTypes[idx].asn1Object
+
+        except IndexError:
             raise error.PyAsn1Error('Type position out of range')
-        else:
-            return self.__namedTypes[idx].getType()
 
     def getPositionByType(self, tagSet):
-        if not self.__tagToPosIdx:
-            idx = self.__namedTypesLen
-            while idx > 0:
-                idx = idx - 1
-                tagMap = self.__namedTypes[idx].getType().getTagMap()
-                for t in tagMap.getPosMap():
-                    if t in self.__tagToPosIdx:
-                        raise error.PyAsn1Error('Duplicate type %s' % (t,))
-                    self.__tagToPosIdx[t] = idx
+        """Return field position by its ASN.1 type.
+
+        Parameters
+        ----------
+        tagSet: :class:`~pysnmp.type.tag.TagSet`
+            ASN.1 tag set distinguishing one ASN.1 type from others.
+
+        Returns
+        -------
+        : :py:class:`int`
+            ASN.1 type position in fields set
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If *tagSet* is not present or ASN.1 types are not unique within callee *NamedTypes*
+        """
         try:
-            return self.__tagToPosIdx[tagSet]
+            return self.__tagToPosMap[tagSet]
+
         except KeyError:
             raise error.PyAsn1Error('Type %s not found' % (tagSet,))
-        
+
     def getNameByPosition(self, idx):
+        """Return field name by its position in fields set.
+
+        Parameters
+        ----------
+        idx: :py:class:`idx`
+            Field index
+
+        Returns
+        -------
+        : :py:class:`str`
+            Field name
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If given field name is not present in callee *NamedTypes*
+        """
         try:
-            return self.__namedTypes[idx].getName()
+            return self.__namedTypes[idx].name
+
         except IndexError:
             raise error.PyAsn1Error('Type position out of range')
+
     def getPositionByName(self, name):
-        if not self.__nameToPosIdx:
-            idx = self.__namedTypesLen
-            while idx > 0:
-                idx = idx - 1
-                n = self.__namedTypes[idx].getName()
-                if n in self.__nameToPosIdx:
-                    raise error.PyAsn1Error('Duplicate name %s' % (n,))
-                self.__nameToPosIdx[n] = idx
+        """Return field position by filed name.
+
+        Parameters
+        ----------
+        name: :py:class:`str`
+            Field name
+
+        Returns
+        -------
+        : :py:class:`int`
+            Field position in fields set
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If *name* is not present or not unique within callee *NamedTypes*
+        """
         try:
-            return self.__nameToPosIdx[name]
+            return self.__nameToPosMap[name]
+
         except KeyError:
             raise error.PyAsn1Error('Name %s not found' % (name,))
 
-    def __buildAmbigiousTagMap(self):
-        ambigiousTypes = ()
-        idx = self.__namedTypesLen
-        while idx > 0:
-            idx = idx - 1
-            t = self.__namedTypes[idx]
-            if t.isOptional or t.isDefaulted:
-                ambigiousTypes = (t, ) + ambigiousTypes
-            else:
-                ambigiousTypes = (t, )
-            self.__ambigiousTypes[idx] = NamedTypes(*ambigiousTypes)
-        
     def getTagMapNearPosition(self, idx):
-        if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
+        """Return ASN.1 types that are allowed at or past given field position.
+
+        Some ASN.1 serialization allow for skipping optional and defaulted fields.
+        Some constructed ASN.1 types allow reordering of the fields. When recovering
+        such objects it may be important to know which types can possibly be
+        present at any given position in the field sets.
+
+        Parameters
+        ----------
+        idx: :py:class:`int`
+            Field index
+
+        Returns
+        -------
+        : :class:`~pyasn1.type.tagmap.TagMap`
+            Map if ASN.1 types allowed at given field position
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If given position is out of fields range
+        """
         try:
-            return self.__ambigiousTypes[idx].getTagMap()
+            return self.__ambiguousTypes[idx].tagMap
+
         except KeyError:
             raise error.PyAsn1Error('Type position out of range')
 
     def getPositionNearType(self, tagSet, idx):
-        if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
+        """Return the closest field position where given ASN.1 type is allowed.
+
+        Some ASN.1 serialization allow for skipping optional and defaulted fields.
+        Some constructed ASN.1 types allow reordering of the fields. When recovering
+        such objects it may be important to know at which field position, in field set,
+        given *tagSet* is allowed at or past *idx* position.
+
+        Parameters
+        ----------
+        tagSet: :class:`~pyasn1.type.tag.TagSet`
+           ASN.1 type which field position to look up
+
+        idx: :py:class:`int`
+            Field position at or past which to perform ASN.1 type look up
+
+        Returns
+        -------
+        : :py:class:`int`
+            Field position in fields set
+
+        Raises
+        ------
+        : :class:`~pyasn1.error.PyAsn1Error`
+            If *tagSet* is not present or not unique within callee *NamedTypes*
+            or *idx* is out of fields range
+        """
         try:
-            return idx+self.__ambigiousTypes[idx].getPositionByType(tagSet)
+            return idx + self.__ambiguousTypes[idx].getPositionByType(tagSet)
+
         except KeyError:
             raise error.PyAsn1Error('Type position out of range')
 
-    def genMinTagSet(self):
-        if self.__minTagSet is None:
-            for t in self.__namedTypes:
-                __type = t.getType()
-                tagSet = getattr(__type,'getMinTagSet',__type.getTagSet)()
-                if self.__minTagSet is None or tagSet < self.__minTagSet:
-                    self.__minTagSet = tagSet
+    def __computeMinTagSet(self):
+        minTagSet = None
+        for namedType in self.__namedTypes:
+            asn1Object = namedType.asn1Object
+
+            try:
+                tagSet = asn1Object.minTagSet
+
+            except AttributeError:
+                tagSet = asn1Object.tagSet
+
+            if minTagSet is None or tagSet < minTagSet:
+                minTagSet = tagSet
+
+        return minTagSet or tag.TagSet()
+
+    @property
+    def minTagSet(self):
+        """Return the minimal TagSet among ASN.1 type in callee *NamedTypes*.
+
+        Some ASN.1 types/serialization protocols require ASN.1 types to be
+        arranged based on their numerical tag value. The *minTagSet* property
+        returns that.
+
+        Returns
+        -------
+        : :class:`~pyasn1.type.tagset.TagSet`
+            Minimal TagSet among ASN.1 types in callee *NamedTypes*
+        """
         return self.__minTagSet
-    
-    def getTagMap(self, uniq=False):
-        if self.__tagMap[uniq] is None:
-            tagMap = tagmap.TagMap()
-            for nt in self.__namedTypes:
-                tagMap = tagMap.clone(
-                    nt.getType(), nt.getType().getTagMap(), uniq
-                    )
-            self.__tagMap[uniq] = tagMap
-        return self.__tagMap[uniq]
+
+    def __computeTagMaps(self, unique):
+        presentTypes = {}
+        skipTypes = {}
+        defaultType = None
+        for namedType in self.__namedTypes:
+            tagMap = namedType.asn1Object.tagMap
+            if isinstance(tagMap, NamedTypes.PostponedError):
+                return tagMap
+            for tagSet in tagMap:
+                if unique and tagSet in presentTypes:
+                    return NamedTypes.PostponedError('Non-unique tagSet %s of %s at %s' % (tagSet, namedType, self))
+                presentTypes[tagSet] = namedType.asn1Object
+            skipTypes.update(tagMap.skipTypes)
+
+            if defaultType is None:
+                defaultType = tagMap.defaultType
+            elif tagMap.defaultType is not None:
+                return NamedTypes.PostponedError('Duplicate default ASN.1 type at %s' % (self,))
+
+        return tagmap.TagMap(presentTypes, skipTypes, defaultType)
+
+    @property
+    def tagMap(self):
+        """Return a *TagMap* object from tags and types recursively.
+
+        Return a :class:`~pyasn1.type.tagmap.TagMap` object by
+        combining tags from *TagMap* objects of children types and
+        associating them with their immediate child type.
+
+        Example
+        -------
+
+        .. code-block:: python
+
+           OuterType ::= CHOICE {
+               innerType INTEGER
+           }
+
+        Calling *.tagMap* on *OuterType* will yield a map like this:
+
+        .. code-block:: python
+
+           Integer.tagSet -> Choice
+        """
+        return self.__nonUniqueTagMap
+
+    @property
+    def tagMapUnique(self):
+        """Return a *TagMap* object from unique tags and types recursively.
+
+        Return a :class:`~pyasn1.type.tagmap.TagMap` object by
+        combining tags from *TagMap* objects of children types and
+        associating them with their immediate child type.
+
+        Example
+        -------
+
+        .. code-block:: python
+
+           OuterType ::= CHOICE {
+               innerType INTEGER
+           }
+
+        Calling *.tagMapUnique* on *OuterType* will yield a map like this:
+
+        .. code-block:: python
+
+           Integer.tagSet -> Choice
+
+        Note
+        ----
+
+        Duplicate *TagSet* objects found in the tree of children
+        types would cause error.
+        """
+        return self.__uniqueTagMap
+
+    @property
+    def hasOptionalOrDefault(self):
+        return self.__hasOptionalOrDefault
+
+    @property
+    def namedTypes(self):
+        return iter(self.__namedTypes)
+
+    @property
+    def requiredComponents(self):
+        return self.__requiredComponents
--- a/third_party/python/pyasn1/pyasn1/type/namedval.py
+++ b/third_party/python/pyasn1/pyasn1/type/namedval.py
@@ -1,46 +1,181 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 # ASN.1 named integers
+#
 from pyasn1 import error
 
-__all__ = [ 'NamedValues' ]
+__all__ = ['NamedValues']
+
+
+class NamedValues(object):
+    """Create named values object.
+
+    The |NamedValues| object represents a collection of string names
+    associated with numeric IDs. These objects are used for giving
+    names to otherwise numerical values.
+
+    |NamedValues| objects are immutable and duck-type Python
+    :class:`dict` object mapping ID to name and vice-versa.
+
+    Parameters
+    ----------
+
+    \*args: variable number of two-element :py:class:`tuple` 
+    \*\*kwargs: keyword parameters of:
+        
+        name: :py:class:`str`
+            Value name
+    
+        value: :py:class:`int`
+                A numerical value
 
-class NamedValues:
-    def __init__(self, *namedValues):
-        self.nameToValIdx = {}; self.valToNameIdx = {}
-        self.namedValues = ()        
-        automaticVal = 1
-        for namedValue in namedValues:
-            if isinstance(namedValue, tuple):
-                name, val = namedValue
+    Examples
+    --------
+
+    >>> nv = namedval.NamedValues('a', 'b', ('c', 0), d=1)
+    >>> nv
+    >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}
+    >>> nv[0]
+    'c'
+    >>> nv['a']
+    2
+    """
+    def __init__(self, *args, **kwargs):
+        self.__names = {}
+        self.__numbers = {}
+
+        anonymousNames = []
+
+        for namedValue in args:
+            if isinstance(namedValue, (tuple, list)):
+                try:
+                    name, number = namedValue
+
+                except ValueError:
+                    raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
+
             else:
-                name = namedValue
-                val = automaticVal
-            if name in self.nameToValIdx:
+                anonymousNames.append(namedValue)
+                continue
+
+            if name in self.__names:
+                raise error.PyAsn1Error('Duplicate name %s' % (name,))
+
+            if number in self.__numbers:
+                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))
+
+            self.__names[name] = number
+            self.__numbers[number] = name
+
+        for name, number in kwargs.items():
+            if name in self.__names:
                 raise error.PyAsn1Error('Duplicate name %s' % (name,))
-            self.nameToValIdx[name] = val
-            if val in self.valToNameIdx:
-                raise error.PyAsn1Error('Duplicate value %s=%s' % (name, val))
-            self.valToNameIdx[val] = name
-            self.namedValues = self.namedValues + ((name, val),)
-            automaticVal = automaticVal + 1
-    def __str__(self): return str(self.namedValues)
-    
+
+            if number in self.__numbers:
+                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))
+
+            self.__names[name] = number
+            self.__numbers[number] = name
+
+        if anonymousNames:
+
+            number = self.__numbers and max(self.__numbers) + 1 or 0
+
+            for name in anonymousNames:
+
+                if name in self.__names:
+                    raise error.PyAsn1Error('Duplicate name %s' % (name,))
+
+                self.__names[name] = number
+                self.__numbers[number] = name
+
+                number += 1
+
+    def __repr__(self):
+        return '%s(%r)' % (self.__class__.__name__, tuple(self.items()))
+
+    def __str__(self):
+        return str(self.items())
+
+    def __eq__(self, other):
+        return dict(self) == other
+
+    def __ne__(self, other):
+        return dict(self) != other
+
+    def __lt__(self, other):
+        return dict(self) < other
+
+    def __le__(self, other):
+        return dict(self) <= other
+
+    def __gt__(self, other):
+        return dict(self) > other
+
+    def __ge__(self, other):
+        return dict(self) >= other
+
+    def __hash__(self):
+        return hash(self.items())
+
+    # Python dict protocol (read-only)
+
+    def __getitem__(self, key):
+        try:
+            return self.__numbers[key]
+
+        except KeyError:
+            return self.__names[key]
+
+    def __len__(self):
+        return len(self.__names)
+
+    def __contains__(self, key):
+        return key in self.__names or key in self.__numbers
+
+    def __iter__(self):
+        return iter(self.__names)
+
+    def values(self):
+        return iter(self.__numbers)
+
+    def keys(self):
+        return iter(self.__names)
+
+    def items(self):
+        for name in self.__names:
+            yield name, self.__names[name]
+
+    # support merging
+
+    def __add__(self, namedValues):
+        return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
+
+    # XXX clone/subtype?
+
+    def clone(self, *args, **kwargs):
+        new = self.__class__(*args, **kwargs)
+        return self + new
+
+    # legacy protocol
+
     def getName(self, value):
-        if value in self.valToNameIdx:
-            return self.valToNameIdx[value]
+        if value in self.__numbers:
+            return self.__numbers[value]
 
     def getValue(self, name):
-        if name in self.nameToValIdx:
-            return self.nameToValIdx[name]
-    
-    def __getitem__(self, i): return self.namedValues[i]
-    def __len__(self): return len(self.namedValues)
+        if name in self.__names:
+            return self.__names[name]
 
-    def __add__(self, namedValues):
-        return self.__class__(*self.namedValues + namedValues)
-    def __radd__(self, namedValues):
-        return self.__class__(*namedValues + tuple(self))
-        
-    def clone(self, *namedValues):
-        return self.__class__(*tuple(self) + namedValues)
+    def getValues(self, *names):
+        try:
+            return [self.__names[name] for name in names]
 
-# XXX clone/subtype?
+        except KeyError:
+            raise error.PyAsn1Error(
+                'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
+            )
--- a/third_party/python/pyasn1/pyasn1/type/tag.py
+++ b/third_party/python/pyasn1/pyasn1/type/tag.py
@@ -1,122 +1,318 @@
-# ASN.1 types tags
-from operator import getitem
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1 import error
 
+__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext',
+           'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed',
+           'tagCategoryImplicit', 'tagCategoryExplicit', 'tagCategoryUntagged',
+           'Tag', 'TagSet']
+
+#: Identifier for ASN.1 class UNIVERSAL
 tagClassUniversal = 0x00
+
+#: Identifier for ASN.1 class APPLICATION
 tagClassApplication = 0x40
+
+#: Identifier for ASN.1 class context-specific
 tagClassContext = 0x80
+
+#: Identifier for ASN.1 class private
 tagClassPrivate = 0xC0
 
+#: Identifier for "simple" ASN.1 structure (e.g. scalar)
 tagFormatSimple = 0x00
+
+#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components)
 tagFormatConstructed = 0x20
 
 tagCategoryImplicit = 0x01
 tagCategoryExplicit = 0x02
 tagCategoryUntagged = 0x04
 
-class Tag:
+
+class Tag(object):
+    """Create ASN.1 tag
+
+    Represents ASN.1 tag that can be attached to a ASN.1 type to make
+    types distinguishable from each other.
+
+    *Tag* objects are immutable and duck-type Python :class:`tuple` objects
+    holding three integer components of a tag.
+
+    Parameters
+    ----------
+    tagClass: :py:class:`int`
+        Tag *class* value
+
+    tagFormat: :py:class:`int`
+        Tag *format* value
+
+    tagId: :py:class:`int`
+        Tag ID value
+    """
     def __init__(self, tagClass, tagFormat, tagId):
         if tagId < 0:
-            raise error.PyAsn1Error(
-                'Negative tag ID (%s) not allowed' % (tagId,)
-                )
-        self.__tag = (tagClass, tagFormat, tagId)
-        self.uniq = (tagClass, tagId)
-        self.__hashedUniqTag = hash(self.uniq)
+            raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % tagId)
+        self.__tagClass = tagClass
+        self.__tagFormat = tagFormat
+        self.__tagId = tagId
+        self.__tagClassId = tagClass, tagId
+        self.__hash = hash(self.__tagClassId)
+
+    def __str__(self):
+        return '[%s:%s:%s]' % (self.__tagClass, self.__tagFormat, self.__tagId)
 
     def __repr__(self):
         return '%s(tagClass=%s, tagFormat=%s, tagId=%s)' % (
-            (self.__class__.__name__,) + self.__tag
-            )
-    # These is really a hotspot -- expose public "uniq" attribute to save on
-    # function calls
-    def __eq__(self, other): return self.uniq == other.uniq
-    def __ne__(self, other): return self.uniq != other.uniq
-    def __lt__(self, other): return self.uniq < other.uniq
-    def __le__(self, other): return self.uniq <= other.uniq
-    def __gt__(self, other): return self.uniq > other.uniq
-    def __ge__(self, other): return self.uniq >= other.uniq
-    def __hash__(self): return self.__hashedUniqTag
-    def __getitem__(self, idx): return self.__tag[idx]
+            (self.__class__.__name__, self.__tagClass, self.__tagFormat, self.__tagId)
+        )
+
+    def __eq__(self, other):
+        return self.__tagClassId == other
+
+    def __ne__(self, other):
+        return self.__tagClassId != other
+
+    def __lt__(self, other):
+        return self.__tagClassId < other
+
+    def __le__(self, other):
+        return self.__tagClassId <= other
+
+    def __gt__(self, other):
+        return self.__tagClassId > other
+
+    def __ge__(self, other):
+        return self.__tagClassId >= other
+
+    def __hash__(self):
+        return self.__hash
+
+    def __getitem__(self, idx):
+        if idx == 0:
+            return self.__tagClass
+        elif idx == 1:
+            return self.__tagFormat
+        elif idx == 2:
+            return self.__tagId
+        else:
+            raise IndexError()
+
+    def __iter__(self):
+        yield self.__tagClass
+        yield self.__tagFormat
+        yield self.__tagId
+
     def __and__(self, otherTag):
-        (tagClass, tagFormat, tagId) = otherTag
-        return self.__class__(
-            self.__tag&tagClass, self.__tag&tagFormat, self.__tag&tagId
-            )
+        return self.__class__(self.__tagClass & otherTag.tagClass,
+                              self.__tagFormat & otherTag.tagFormat,
+                              self.__tagId & otherTag.tagId)
+
     def __or__(self, otherTag):
-        (tagClass, tagFormat, tagId) = otherTag
-        return self.__class__(
-            self.__tag[0]|tagClass,
-            self.__tag[1]|tagFormat,
-            self.__tag[2]|tagId
-            )
-    def asTuple(self): return self.__tag  # __getitem__() is slow
-    
-class TagSet:
+        return self.__class__(self.__tagClass | otherTag.tagClass,
+                              self.__tagFormat | otherTag.tagFormat,
+                              self.__tagId | otherTag.tagId)
+
+    @property
+    def tagClass(self):
+        """ASN.1 tag class
+
+        Returns
+        -------
+        : :py:class:`int`
+            Tag class
+        """
+        return self.__tagClass
+
+    @property
+    def tagFormat(self):
+        """ASN.1 tag format
+
+        Returns
+        -------
+        : :py:class:`int`
+            Tag format
+        """
+        return self.__tagFormat
+
+    @property
+    def tagId(self):
+        """ASN.1 tag ID
+
+        Returns
+        -------
+        : :py:class:`int`
+            Tag ID
+        """
+        return self.__tagId
+
+
+class TagSet(object):
+    """Create a collection of ASN.1 tags
+
+    Represents a combination of :class:`~pyasn1.type.tag.Tag` objects
+    that can be attached to a ASN.1 type to make types distinguishable
+    from each other.
+
+    *TagSet* objects are immutable and duck-type Python :class:`tuple` objects
+    holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects.
+
+    Parameters
+    ----------
+    baseTag: :class:`~pyasn1.type.tag.Tag`
+        Base *Tag* object. This tag survives IMPLICIT tagging.
+
+    *superTags: :class:`~pyasn1.type.tag.Tag`
+        Additional *Tag* objects taking part in subtyping.
+    """
     def __init__(self, baseTag=(), *superTags):
         self.__baseTag = baseTag
         self.__superTags = superTags
-        self.__hashedSuperTags = hash(superTags)
-        _uniq = ()
-        for t in superTags:
-            _uniq = _uniq + t.uniq
-        self.uniq = _uniq
+        self.__superTagsClassId = tuple(
+            [(superTag.tagClass, superTag.tagId) for superTag in superTags]
+        )
         self.__lenOfSuperTags = len(superTags)
-        
+        self.__hash = hash(self.__superTagsClassId)
+
+    def __str__(self):
+        return self.__superTags and '+'.join([str(x) for x in self.__superTags]) or '[untagged]'
+
     def __repr__(self):
         return '%s(%s)' % (
-            self.__class__.__name__,
-            ', '.join([repr(x) for x in self.__superTags])
-            )
+            self.__class__.__name__, '(), ' + ', '.join([repr(x) for x in self.__superTags])
+        )
 
     def __add__(self, superTag):
-        return self.__class__(
-            self.__baseTag, *self.__superTags + (superTag,)
-            )
+        return self.__class__(self.__baseTag, *self.__superTags + (superTag,))
+
     def __radd__(self, superTag):
-        return self.__class__(
-            self.__baseTag, *(superTag,) + self.__superTags
-            )
+        return self.__class__(self.__baseTag, *(superTag,) + self.__superTags)
+
+    def __getitem__(self, i):
+        if i.__class__ is slice:
+            return self.__class__(self.__baseTag, *self.__superTags[i])
+        else:
+            return self.__superTags[i]
+
+    def __eq__(self, other):
+        return self.__superTagsClassId == other
+
+    def __ne__(self, other):
+        return self.__superTagsClassId != other
+
+    def __lt__(self, other):
+        return self.__superTagsClassId < other
+
+    def __le__(self, other):
+        return self.__superTagsClassId <= other
+
+    def __gt__(self, other):
+        return self.__superTagsClassId > other
+
+    def __ge__(self, other):
+        return self.__superTagsClassId >= other
+
+    def __hash__(self):
+        return self.__hash
+
+    def __len__(self):
+        return self.__lenOfSuperTags
+
+    @property
+    def baseTag(self):
+        """Return base ASN.1 tag
+
+        Returns
+        -------
+        : :class:`~pyasn1.type.tag.Tag`
+            Base tag of this *TagSet*
+        """
+        return self.__baseTag
+
+    @property
+    def superTags(self):
+        """Return ASN.1 tags
+
+        Returns
+        -------
+        : :py:class:`tuple`
+            Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains
+        """
+        return self.__superTags
 
     def tagExplicitly(self, superTag):
-        tagClass, tagFormat, tagId = superTag
-        if tagClass == tagClassUniversal:
-            raise error.PyAsn1Error(
-                'Can\'t tag with UNIVERSAL-class tag'
-                )
-        if tagFormat != tagFormatConstructed:
-            superTag = Tag(tagClass, tagFormatConstructed, tagId)
+        """Return explicitly tagged *TagSet*
+
+        Create a new *TagSet* representing callee *TagSet* explicitly tagged
+        with passed tag(s). With explicit tagging mode, new tags are appended
+        to existing tag(s).
+
+        Parameters
+        ----------
+        superTag: :class:`~pyasn1.type.tag.Tag`
+            *Tag* object to tag this *TagSet*
+
+        Returns
+        -------
+        : :class:`~pyasn1.type.tag.TagSet`
+            New *TagSet* object
+        """
+        if superTag.tagClass == tagClassUniversal:
+            raise error.PyAsn1Error("Can't tag with UNIVERSAL class tag")
+        if superTag.tagFormat != tagFormatConstructed:
+            superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId)
         return self + superTag
 
     def tagImplicitly(self, superTag):
-        tagClass, tagFormat, tagId = superTag
+        """Return implicitly tagged *TagSet*
+
+        Create a new *TagSet* representing callee *TagSet* implicitly tagged
+        with passed tag(s). With implicit tagging mode, new tag(s) replace the
+        last existing tag.
+
+        Parameters
+        ----------
+        superTag: :class:`~pyasn1.type.tag.Tag`
+            *Tag* object to tag this *TagSet*
+
+        Returns
+        -------
+        : :class:`~pyasn1.type.tag.TagSet`
+            New *TagSet* object
+        """
         if self.__superTags:
-            superTag = Tag(tagClass, self.__superTags[-1][1], tagId)
+            superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId)
         return self[:-1] + superTag
 
-    def getBaseTag(self): return self.__baseTag
-    def __getitem__(self, idx):
-        if isinstance(idx, slice):
-            return self.__class__(
-               self.__baseTag, *getitem(self.__superTags, idx)
-            )
-        return self.__superTags[idx]
-    def __eq__(self, other): return self.uniq == other.uniq
-    def __ne__(self, other): return self.uniq != other.uniq
-    def __lt__(self, other): return self.uniq < other.uniq
-    def __le__(self, other): return self.uniq <= other.uniq
-    def __gt__(self, other): return self.uniq > other.uniq
-    def __ge__(self, other): return self.uniq >= other.uniq
-    def __hash__(self): return self.__hashedSuperTags
-    def __len__(self): return self.__lenOfSuperTags
     def isSuperTagSetOf(self, tagSet):
+        """Test type relationship against given *TagSet*
+
+        The callee is considered to be a supertype of given *TagSet*
+        tag-wise if all tags in *TagSet* are present in the callee and
+        they are in the same order.
+
+        Parameters
+        ----------
+        tagSet: :class:`~pyasn1.type.tag.TagSet`
+            *TagSet* object to evaluate against the callee
+
+        Returns
+        -------
+        : :py:class:`bool`
+            `True` if callee is a supertype of *tagSet*
+        """
         if len(tagSet) < self.__lenOfSuperTags:
-            return
-        idx = self.__lenOfSuperTags - 1
-        while idx >= 0:
-            if self.__superTags[idx] != tagSet[idx]:
-                return
-            idx = idx - 1
-        return 1
-    
-def initTagSet(tag): return TagSet(tag, tag)
+            return False
+        return self.__superTags == tagSet[:self.__lenOfSuperTags]
+
+    # Backward compatibility
+
+    def getBaseTag(self):
+        return self.__baseTag
+
+def initTagSet(tag):
+    return TagSet(tag, tag)
--- a/third_party/python/pyasn1/pyasn1/type/tagmap.py
+++ b/third_party/python/pyasn1/pyasn1/type/tagmap.py
@@ -1,52 +1,102 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 from pyasn1 import error
 
-class TagMap:
-    def __init__(self, posMap={}, negMap={}, defType=None):
-        self.__posMap = posMap.copy()
-        self.__negMap = negMap.copy()
-        self.__defType = defType
-        
+__all__ = ['TagMap']
+
+
+class TagMap(object):
+    """Map *TagSet* objects to ASN.1 types
+
+    Create an object mapping *TagSet* object to ASN.1 type.
+
+    *TagMap* objects are immutable and duck-type read-only Python
+    :class:`dict` objects holding *TagSet* objects as keys and ASN.1
+    type objects as values.
+
+    Parameters
+    ----------
+    presentTypes: :py:class:`dict`
+        Map of :class:`~pyasn1.type.tag.TagSet` to ASN.1 objects considered
+        as being unconditionally present in the *TagMap*.
+
+    skipTypes: :py:class:`dict`
+        A collection of :class:`~pyasn1.type.tag.TagSet` objects considered
+        as absent in the *TagMap* even when *defaultType* is present.
+
+    defaultType: ASN.1 type object
+        An ASN.1 type object callee *TagMap* returns for any *TagSet* key not present
+        in *presentTypes* (unless given key is present in *skipTypes*).
+    """
+    def __init__(self, presentTypes=None, skipTypes=None, defaultType=None):
+        self.__presentTypes = presentTypes or {}
+        self.__skipTypes = skipTypes or {}
+        self.__defaultType = defaultType
+
     def __contains__(self, tagSet):
-        return tagSet in self.__posMap or \
-               self.__defType is not None and tagSet not in self.__negMap
+        return (tagSet in self.__presentTypes or
+                self.__defaultType is not None and tagSet not in self.__skipTypes)
 
     def __getitem__(self, tagSet):
-        if tagSet in self.__posMap:
-            return self.__posMap[tagSet]
-        elif tagSet in self.__negMap:
-            raise error.PyAsn1Error('Key in negative map')
-        elif self.__defType is not None:
-            return self.__defType
-        else:
-            raise KeyError()
+        try:
+            return self.__presentTypes[tagSet]
+        except KeyError:
+            if self.__defaultType is None:
+                raise KeyError()
+            elif tagSet in self.__skipTypes:
+                raise error.PyAsn1Error('Key in negative map')
+            else:
+                return self.__defaultType
+
+    def __iter__(self):
+        return iter(self.__presentTypes)
 
     def __repr__(self):
-        s = '%r/%r' % (self.__posMap, self.__negMap)
-        if self.__defType is not None:
-            s = s + '/%r' % (self.__defType,)
+        s = self.__class__.__name__ + '('
+        if self.__presentTypes:
+            s += 'presentTypes=%r, ' % (self.__presentTypes,)
+        if self.__skipTypes:
+            s += 'skipTypes=%r, ' % (self.__skipTypes,)
+        if self.__defaultType is not None:
+            s += 'defaultType=%r' % (self.__defaultType,)
+        return s + ')'
+
+    def __str__(self):
+        s = self.__class__.__name__ + ': '
+        if self.__presentTypes:
+            s += 'presentTypes: %s, ' % ', '.join([x.prettyPrintType() for x in self.__presentTypes.values()])
+        if self.__skipTypes:
+            s += 'skipTypes: %s, ' % ', '.join([x.prettyPrintType() for x in self.__skipTypes.values()])
+        if self.__defaultType is not None:
+            s += 'defaultType: %s, ' % self.__defaultType.prettyPrintType()
         return s
 
-    def clone(self, parentType, tagMap, uniq=False):
-        if self.__defType is not None and tagMap.getDef() is not None:
-            raise error.PyAsn1Error('Duplicate default value at %s' % (self,))
-        if tagMap.getDef() is not None:
-            defType = tagMap.getDef()
-        else:
-            defType = self.__defType
-            
-        posMap = self.__posMap.copy()
-        for k in tagMap.getPosMap():
-            if uniq and k in posMap:
-                raise error.PyAsn1Error('Duplicate positive key %s' % (k,))
-            posMap[k] = parentType
+    @property
+    def presentTypes(self):
+        """Return *TagSet* to ASN.1 type map present in callee *TagMap*"""
+        return self.__presentTypes
+
+    @property
+    def skipTypes(self):
+        """Return *TagSet* collection unconditionally absent in callee *TagMap*"""
+        return self.__skipTypes
 
-        negMap = self.__negMap.copy()
-        negMap.update(tagMap.getNegMap())
-        
-        return self.__class__(
-            posMap, negMap, defType,
-            )
+    @property
+    def defaultType(self):
+        """Return default ASN.1 type being returned for any missing *TagSet*"""
+        return self.__defaultType
+
+    # Backward compatibility
 
-    def getPosMap(self): return self.__posMap.copy()
-    def getNegMap(self): return self.__negMap.copy()
-    def getDef(self): return self.__defType
+    def getPosMap(self):
+        return self.presentTypes
+
+    def getNegMap(self):
+        return self.skipTypes
+
+    def getDef(self):
+        return self.defaultType
--- a/third_party/python/pyasn1/pyasn1/type/univ.py
+++ b/third_party/python/pyasn1/pyasn1/type/univ.py
@@ -1,1042 +1,2875 @@
-# ASN.1 "universal" data types
-import operator, sys
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import math
 from pyasn1.type import base, tag, constraint, namedtype, namedval, tagmap
 from pyasn1.codec.ber import eoo
-from pyasn1.compat import octets
+from pyasn1.compat import octets, integer, binary
 from pyasn1 import error
 
+NoValue = base.NoValue
+noValue = NoValue()
+
+__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
+           'ObjectIdentifier', 'Real', 'Enumerated', 'SequenceOfAndSetOfBase', 'SequenceOf',
+           'SetOf', 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
+           'NoValue', 'noValue']
+
 # "Simple" ASN.1 types (yet incomplete)
 
+
 class Integer(base.AbstractSimpleAsn1Item):
-    tagSet = baseTagSet = tag.initTagSet(
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
+
+    Parameters
+    ----------
+    value : :class:`int`, :class:`str` or |ASN.1| object
+        Python integer or string literal or |ASN.1| class instance.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+        Object representing non-default symbolic aliases for numbers
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
-        )
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+    #: representing symbolic aliases for numbers
     namedValues = namedval.NamedValues()
-    def __init__(self, value=None, tagSet=None, subtypeSpec=None,
-                 namedValues=None):
-        if namedValues is None:
-            self.__namedValues = self.namedValues
+
+    # Optimization for faster codec lookup
+    typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+    def __init__(self, value=noValue, **kwargs):
+        if 'namedValues' not in kwargs:
+            kwargs['namedValues'] = self.namedValues
+
+        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+    def __repr__(self):
+        if self.namedValues is not self.__class__.namedValues:
+            return '%s, %r)' % (base.AbstractSimpleAsn1Item.__repr__(self)[:-1], self.namedValues)
         else:
-            self.__namedValues = namedValues
-        base.AbstractSimpleAsn1Item.__init__(
-            self, value, tagSet, subtypeSpec
-            )
-
-    def __and__(self, value): return self.clone(self._value & value)
-    def __rand__(self, value): return self.clone(value & self._value)
-    def __or__(self, value): return self.clone(self._value | value)
-    def __ror__(self, value): return self.clone(value | self._value)
-    def __xor__(self, value): return self.clone(self._value ^ value)
-    def __rxor__(self, value): return self.clone(value ^ self._value)
-    def __lshift__(self, value): return self.clone(self._value << value)
-    def __rshift__(self, value): return self.clone(self._value >> value)
-
-    def __add__(self, value): return self.clone(self._value + value)
-    def __radd__(self, value): return self.clone(value + self._value)
-    def __sub__(self, value): return self.clone(self._value - value)
-    def __rsub__(self, value): return self.clone(value - self._value)
-    def __mul__(self, value): return self.clone(self._value * value)
-    def __rmul__(self, value): return self.clone(value * self._value)
-    def __mod__(self, value): return self.clone(self._value % value)
-    def __rmod__(self, value): return self.clone(value % self._value)
-    def __pow__(self, value, modulo=None): return self.clone(pow(self._value, value, modulo))
-    def __rpow__(self, value): return self.clone(pow(value, self._value))
+            return base.AbstractSimpleAsn1Item.__repr__(self)
+
+    def __and__(self, value):
+        return self.clone(self._value & value)
+
+    def __rand__(self, value):
+        return self.clone(value & self._value)
+
+    def __or__(self, value):
+        return self.clone(self._value | value)
+
+    def __ror__(self, value):
+        return self.clone(value | self._value)
+
+    def __xor__(self, value):
+        return self.clone(self._value ^ value)
+
+    def __rxor__(self, value):
+        return self.clone(value ^ self._value)
+
+    def __lshift__(self, value):
+        return self.clone(self._value << value)
+
+    def __rshift__(self, value):
+        return self.clone(self._value >> value)
+
+    def __add__(self, value):
+        return self.clone(self._value + value)
+
+    def __radd__(self, value):
+        return self.clone(value + self._value)
+
+    def __sub__(self, value):
+        return self.clone(self._value - value)
+
+    def __rsub__(self, value):
+        return self.clone(value - self._value)
+
+    def __mul__(self, value):
+        return self.clone(self._value * value)
+
+    def __rmul__(self, value):
+        return self.clone(value * self._value)
+
+    def __mod__(self, value):
+        return self.clone(self._value % value)
+
+    def __rmod__(self, value):
+        return self.clone(value % self._value)
+
+    def __pow__(self, value, modulo=None):
+        return self.clone(pow(self._value, value, modulo))
+
+    def __rpow__(self, value):
+        return self.clone(pow(value, self._value))
+
+    def __floordiv__(self, value):
+        return self.clone(self._value // value)
+
+    def __rfloordiv__(self, value):
+        return self.clone(value // self._value)
 
     if sys.version_info[0] <= 2:
-        def __div__(self, value):  return self.clone(self._value // value)
-        def __rdiv__(self, value):  return self.clone(value // self._value)
+        def __div__(self, value):
+            if isinstance(value, float):
+                return Real(self._value / value)
+            else:
+                return self.clone(self._value / value)
+
+        def __rdiv__(self, value):
+            if isinstance(value, float):
+                return Real(value / self._value)
+            else:
+                return self.clone(value / self._value)
     else:
-        def __truediv__(self, value):  return self.clone(self._value / value)
-        def __rtruediv__(self, value):  return self.clone(value / self._value)
-        def __divmod__(self, value):  return self.clone(self._value // value)
-        def __rdivmod__(self, value):  return self.clone(value // self._value)
+        def __truediv__(self, value):
+            return Real(self._value / value)
+
+        def __rtruediv__(self, value):
+            return Real(value / self._value)
+
+        def __divmod__(self, value):
+            return self.clone(divmod(self._value, value))
+
+        def __rdivmod__(self, value):
+            return self.clone(divmod(value, self._value))
 
         __hash__ = base.AbstractSimpleAsn1Item.__hash__
 
-    def __int__(self): return int(self._value)
+    def __int__(self):
+        return int(self._value)
+
     if sys.version_info[0] <= 2:
-        def __long__(self): return long(self._value)
-    def __float__(self): return float(self._value)    
-    def __abs__(self): return abs(self._value)
-    def __index__(self): return int(self._value)
-
-    def __lt__(self, value): return self._value < value
-    def __le__(self, value): return self._value <= value
-    def __eq__(self, value): return self._value == value
-    def __ne__(self, value): return self._value != value
-    def __gt__(self, value): return self._value > value
-    def __ge__(self, value): return self._value >= value
+        def __long__(self):
+            return long(self._value)
+
+    def __float__(self):
+        return float(self._value)
+
+    def __abs__(self):
+        return self.clone(abs(self._value))
+
+    def __index__(self):
+        return int(self._value)
+
+    def __pos__(self):
+        return self.clone(+self._value)
+
+    def __neg__(self):
+        return self.clone(-self._value)
+
+    def __invert__(self):
+        return self.clone(~self._value)
+
+    def __round__(self, n=0):
+        r = round(self._value, n)
+        if n:
+            return self.clone(r)
+        else:
+            return r
+
+    def __floor__(self):
+        return math.floor(self._value)
+
+    def __ceil__(self):
+        return math.ceil(self._value)
+
+    if sys.version_info[0:2] > (2, 5):
+        def __trunc__(self):
+            return self.clone(math.trunc(self._value))
+
+    def __lt__(self, value):
+        return self._value < value
+
+    def __le__(self, value):
+        return self._value <= value
+
+    def __eq__(self, value):
+        return self._value == value
+
+    def __ne__(self, value):
+        return self._value != value
+
+    def __gt__(self, value):
+        return self._value > value
+
+    def __ge__(self, value):
+        return self._value >= value
 
     def prettyIn(self, value):
-        if not isinstance(value, str):
-            try:
-                return int(value)
-            except:
-                raise error.PyAsn1Error(
-                    'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
-                    )
-        r = self.__namedValues.getValue(value)
-        if r is not None:
-            return r
         try:
             return int(value)
-        except:
-            raise error.PyAsn1Error(
-                'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
+
+        except ValueError:
+            try:
+                return self.namedValues[value]
+
+            except KeyError:
+                raise error.PyAsn1Error(
+                    'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
                 )
 
     def prettyOut(self, value):
-        r = self.__namedValues.getName(value)
-        return r is None and str(value) or repr(r)
-
-    def getNamedValues(self): return self.__namedValues
-
-    def clone(self, value=None, tagSet=None, subtypeSpec=None,
-              namedValues=None):
-        if value is None and tagSet is None and subtypeSpec is None \
-               and namedValues is None:
-            return self
-        if value is None:
-            value = self._value
-        if tagSet is None:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        if namedValues is None:
-            namedValues = self.__namedValues
-        return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
-    def subtype(self, value=None, implicitTag=None, explicitTag=None,
-                subtypeSpec=None, namedValues=None):
-        if value is None:
-            value = self._value
-        if implicitTag is not None:
-            tagSet = self._tagSet.tagImplicitly(implicitTag)
-        elif explicitTag is not None:
-            tagSet = self._tagSet.tagExplicitly(explicitTag)
-        else:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        else:
-            subtypeSpec = subtypeSpec + self._subtypeSpec
-        if namedValues is None:
-            namedValues = self.__namedValues
-        else:
-            namedValues = namedValues + self.__namedValues
-        return self.__class__(value, tagSet, subtypeSpec, namedValues)
+        try:
+            return repr(self.namedValues[value])
+
+        except KeyError:
+            return str(value)
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`int`, :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+        namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+            Object representing symbolic aliases for numbers to use instead of inheriting from caller
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`int`, :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of 
+            inheriting one from the caller.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Add ASN.1 constraints object to one of the caller, then
+            use the result as new object's ASN.1 constraints.
+
+        namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+            Add given object representing symbolic aliases for numbers
+            to one of the caller, then use the result as new object's
+            named numbers.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+    # backward compatibility
+
+    def getNamedValues(self):
+        return self.namedValues
+
 
 class Boolean(Integer):
-    tagSet = baseTagSet = tag.initTagSet(
+    __doc__ = Integer.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
-        )
-    subtypeSpec = Integer.subtypeSpec+constraint.SingleValueConstraint(0,1)
-    namedValues = Integer.namedValues.clone(('False', 0), ('True', 1))
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
+
+    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+    #: representing symbolic aliases for numbers
+    namedValues = namedval.NamedValues(('False', 0), ('True', 1))
+
+    # Optimization for faster codec lookup
+    typeId = Integer.getTypeId()
+
 
 class BitString(base.AbstractSimpleAsn1Item):
-    tagSet = baseTagSet = tag.initTagSet(
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple
+    of bits) and :class:`int` objects.
+
+    Parameters
+    ----------
+    value : :class:`int`, :class:`str` or |ASN.1| object
+        Python integer or string literal representing binary or hexadecimal
+        number or sequence of integer bits or |ASN.1| object.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+        Object representing non-default symbolic aliases for numbers
+
+    binValue: :py:class:`str`
+        Binary string initializer to use instead of the *value*.
+        Example: '10110011'.
+
+    hexValue: :py:class:`str`
+        Hexadecimal string initializer to use instead of the *value*.
+        Example: 'DEADBEEF'.
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
-        )
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+    #: representing symbolic aliases for numbers
     namedValues = namedval.NamedValues()
-    def __init__(self, value=None, tagSet=None, subtypeSpec=None,
-                 namedValues=None):
-        if namedValues is None:
-            self.__namedValues = self.namedValues
-        else:
-            self.__namedValues = namedValues
-        base.AbstractSimpleAsn1Item.__init__(
-            self, value, tagSet, subtypeSpec
-            )
-
-    def clone(self, value=None, tagSet=None, subtypeSpec=None,
-              namedValues=None):
-        if value is None and tagSet is None and subtypeSpec is None \
-               and namedValues is None:
+
+    # Optimization for faster codec lookup
+    typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+    defaultBinValue = defaultHexValue = noValue
+
+    if sys.version_info[0] < 3:
+        SizedIntegerBase = long
+    else:
+        SizedIntegerBase = int
+
+    class SizedInteger(SizedIntegerBase):
+        bitLength = leadingZeroBits = None
+
+        def setBitLength(self, bitLength):
+            self.bitLength = bitLength
+            self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
             return self
-        if value is None:
-            value = self._value
-        if tagSet is None:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        if namedValues is None:
-            namedValues = self.__namedValues
-        return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
-    def subtype(self, value=None, implicitTag=None, explicitTag=None,
-                subtypeSpec=None, namedValues=None):
-        if value is None:
-            value = self._value
-        if implicitTag is not None:
-            tagSet = self._tagSet.tagImplicitly(implicitTag)
-        elif explicitTag is not None:
-            tagSet = self._tagSet.tagExplicitly(explicitTag)
-        else:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        else:
-            subtypeSpec = subtypeSpec + self._subtypeSpec
-        if namedValues is None:
-            namedValues = self.__namedValues
-        else:
-            namedValues = namedValues + self.__namedValues
-        return self.__class__(value, tagSet, subtypeSpec, namedValues)
-
-    def __str__(self): return str(tuple(self))
+
+        def __len__(self):
+            if self.bitLength is None:
+                self.setBitLength(integer.bitLength(self))
+
+            return self.bitLength
+
+    def __init__(self, value=noValue, **kwargs):
+        if value is noValue or value is None:
+            if kwargs:
+                try:
+                    value = self.fromBinaryString(kwargs.pop('binValue'))
+
+                except KeyError:
+                    pass
+
+                try:
+                    value = self.fromHexString(kwargs.pop('hexValue'))
+
+                except KeyError:
+                    pass
+
+        if value is noValue or value is None:
+            if self.defaultBinValue is not noValue:
+                value = self.fromBinaryString(self.defaultBinValue)
+
+            elif self.defaultHexValue is not noValue:
+                value = self.fromHexString(self.defaultHexValue)
+
+        if 'namedValues' not in kwargs:
+            kwargs['namedValues'] = self.namedValues
+
+        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value : :class:`int`, :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+        namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+            Class instance representing BitString type enumerations
+
+        binValue: :py:class:`str`
+            Binary string initializer to use instead of the *value*.
+            Example: '10110011'.
+
+        hexValue: :py:class:`str`
+            Hexadecimal string initializer to use instead of the *value*.
+            Example: 'DEADBEEF'.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`int`, :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Add ASN.1 constraints object to one of the caller, then
+            use the result as new object's ASN.1 constraints.
+
+        namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
+            Add given object representing symbolic aliases for numbers
+            to one of the caller, then use the result as new object's
+            named numbers.
+
+        binValue: :py:class:`str`
+            Binary string initializer to use instead of the *value*.
+            Example: '10110011'.
+
+        hexValue: :py:class:`str`
+            Hexadecimal string initializer to use instead of the *value*.
+            Example: 'DEADBEEF'.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+    def __str__(self):
+        return self.asBinary()
+
+    def __eq__(self, other):
+        other = self.prettyIn(other)
+        return self is other or self._value == other and len(self._value) == len(other)
+
+    def __ne__(self, other):
+        other = self.prettyIn(other)
+        return self._value != other or len(self._value) != len(other)
+
+    def __lt__(self, other):
+        other = self.prettyIn(other)
+        return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
+
+    def __le__(self, other):
+        other = self.prettyIn(other)
+        return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
+
+    def __gt__(self, other):
+        other = self.prettyIn(other)
+        return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
+
+    def __ge__(self, other):
+        other = self.prettyIn(other)
+        return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
 
     # Immutable sequence object protocol
 
     def __len__(self):
-        if self._len is None:
-            self._len = len(self._value)
-        return self._len
+        return len(self._value)
+
     def __getitem__(self, i):
-        if isinstance(i, slice):
-            return self.clone(operator.getitem(self._value, i))
+        if i.__class__ is slice:
+            return self.clone([self[x] for x in range(*i.indices(len(self)))])
         else:
-            return self._value[i]
-
-    def __add__(self, value): return self.clone(self._value + value)
-    def __radd__(self, value): return self.clone(value + self._value)
-    def __mul__(self, value): return self.clone(self._value * value)
-    def __rmul__(self, value): return self * value
+            length = len(self._value) - 1
+            if i > length or i < 0:
+                raise IndexError('bit index out of range')
+            return (self._value >> (length - i)) & 1
+
+    def __iter__(self):
+        length = len(self._value)
+        while length:
+            length -= 1
+            yield (self._value >> length) & 1
+
+    def __reversed__(self):
+        return reversed(tuple(self))
+
+    # arithmetic operators
+
+    def __add__(self, value):
+        value = self.prettyIn(value)
+        return self.clone(self.SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
+
+    def __radd__(self, value):
+        value = self.prettyIn(value)
+        return self.clone(self.SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
+
+    def __mul__(self, value):
+        bitString = self._value
+        while value > 1:
+            bitString <<= len(self._value)
+            bitString |= self._value
+            value -= 1
+        return self.clone(bitString)
+
+    def __rmul__(self, value):
+        return self * value
+
+    def __lshift__(self, count):
+        return self.clone(self.SizedInteger(self._value << count).setBitLength(len(self._value) + count))
+
+    def __rshift__(self, count):
+        return self.clone(self.SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
+
+    def __int__(self):
+        return self._value
+
+    def __float__(self):
+        return float(self._value)
+
+    if sys.version_info[0] < 3:
+        def __long__(self):
+            return self._value
+
+    def asNumbers(self):
+        """Get |ASN.1| value as a sequence of 8-bit integers.
+
+        If |ASN.1| object length is not a multiple of 8, result
+        will be left-padded with zeros.
+        """
+        return tuple(octets.octs2ints(self.asOctets()))
+
+    def asOctets(self):
+        """Get |ASN.1| value as a sequence of octets.
+
+        If |ASN.1| object length is not a multiple of 8, result
+        will be left-padded with zeros.
+        """
+        return integer.to_bytes(self._value, length=len(self))
+
+    def asInteger(self):
+        """Get |ASN.1| value as a single integer value.
+        """
+        return self._value
+
+    def asBinary(self):
+        """Get |ASN.1| value as a text string of bits.
+        """
+        binString = binary.bin(self._value)[2:]
+        return '0' * (len(self._value) - len(binString)) + binString
+
+    @classmethod
+    def fromHexString(cls, value):
+        """Create a |ASN.1| object initialized from the hex string.
+        
+        Parameters
+        ----------
+        value: :class:`str`
+            Text string like 'DEADBEEF'
+        """
+        try:
+            return cls.SizedInteger(value, 16).setBitLength(len(value) * 4)
+
+        except ValueError:
+            raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
+
+    @classmethod
+    def fromBinaryString(cls, value):
+        """Create a |ASN.1| object initialized from a string of '0' and '1'.
+
+        Parameters
+        ----------
+        value: :class:`str`
+            Text string like '1010111'
+        """
+        try:
+            return cls.SizedInteger(value or '0', 2).setBitLength(len(value))
+
+        except ValueError:
+            raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
+
+    @classmethod
+    def fromOctetString(cls, value, padding=0):
+        """Create a |ASN.1| object initialized from a string.
+
+        Parameters
+        ----------
+        value: :class:`str` (Py2) or :class:`bytes` (Py3)
+            Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
+        """
+        return cls(cls.SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding))
 
     def prettyIn(self, value):
-        r = []
-        if not value:
-            return ()
-        elif isinstance(value, str):
-            if value[0] == '\'':
+        if octets.isStringType(value):
+            if not value:
+                return self.SizedInteger(0).setBitLength(0)
+
+            elif value[0] == '\'':  # "'1011'B" -- ASN.1 schema representation (deprecated)
                 if value[-2:] == '\'B':
-                    for v in value[1:-2]:
-                        if v == '0':
-                            r.append(0)
-                        elif v == '1':
-                            r.append(1)
-                        else:
-                            raise error.PyAsn1Error(
-                                'Non-binary BIT STRING initializer %s' % (v,)
-                                )
-                    return tuple(r)
+                    return self.fromBinaryString(value[1:-2])
                 elif value[-2:] == '\'H':
-                    for v in value[1:-2]:
-                        i = 4
-                        v = int(v, 16)
-                        while i:
-                            i = i - 1
-                            r.append((v>>i)&0x01)
-                    return tuple(r)
+                    return self.fromHexString(value[1:-2])
                 else:
                     raise error.PyAsn1Error(
                         'Bad BIT STRING value notation %s' % (value,)
-                        )                
-            else:
-                for i in value.split(','):
-                    j = self.__namedValues.getValue(i)
-                    if j is None:
-                        raise error.PyAsn1Error(
-                            'Unknown bit identifier \'%s\'' % (i,)
-                            )
-                    if j >= len(r):
-                        r.extend([0]*(j-len(r)+1))
-                    r[j] = 1
-                return tuple(r)
+                    )
+
+            elif self.namedValues and not value.isdigit():  # named bits like 'Urgent, Active'
+                names = [x.strip() for x in value.split(',')]
+
+                try:
+
+                    bitPositions = [self.namedValues[name] for name in names]
+
+                except KeyError:
+                    raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
+
+                rightmostPosition = max(bitPositions)
+
+                number = 0
+                for bitPosition in bitPositions:
+                    number |= 1 << (rightmostPosition - bitPosition)
+
+                return self.SizedInteger(number).setBitLength(rightmostPosition + 1)
+
+            elif value.startswith('0x'):
+                return self.fromHexString(value[2:])
+
+            elif value.startswith('0b'):
+                return self.fromBinaryString(value[2:])
+
+            else:  # assume plain binary string like '1011'
+                return self.fromBinaryString(value)
+
         elif isinstance(value, (tuple, list)):
-            r = tuple(value)
-            for b in r:
-                if b and b != 1:
-                    raise error.PyAsn1Error(
-                        'Non-binary BitString initializer \'%s\'' % (r,)
-                        )
-            return r
-        elif isinstance(value, BitString):
-            return tuple(value)
+            return self.fromBinaryString(''.join([b and '1' or '0' for b in value]))
+
+        elif isinstance(value, (self.SizedInteger, BitString)):
+            return self.SizedInteger(value).setBitLength(len(value))
+
+        elif isinstance(value, intTypes):
+            return self.SizedInteger(value)
+
         else:
             raise error.PyAsn1Error(
                 'Bad BitString initializer type \'%s\'' % (value,)
-                )
+            )
 
     def prettyOut(self, value):
-        return '\"\'%s\'B\"' % ''.join([str(x) for x in value])
+        return '\'%s\'' % str(self)
+
+
+try:
+    # noinspection PyStatementEffect
+    all
+
+except NameError:  # Python 2.4
+    # noinspection PyShadowingBuiltins
+    def all(iterable):
+        for element in iterable:
+            if not element:
+                return False
+        return True
+
 
 class OctetString(base.AbstractSimpleAsn1Item):
-    tagSet = baseTagSet = tag.initTagSet(
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.
+    When used in Unicode context, |ASN.1| type assumes "|encoding|" serialization.
+
+    Parameters
+    ----------
+    value : :class:`str`, :class:`bytes` or |ASN.1| object
+        string (Python 2) or bytes (Python 3), alternatively unicode object
+        (Python 2) or string (Python 3) representing character string to be
+        serialized into octets (note `encoding` parameter) or |ASN.1| object.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    encoding: :py:class:`str`
+        Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
+        :class:`str` (Python 3) the payload when |ASN.1| object is used
+        in text string context.
+
+    binValue: :py:class:`str`
+        Binary string initializer to use instead of the *value*.
+        Example: '10110011'.
+        
+    hexValue: :py:class:`str`
+        Hexadecimal string initializer to use instead of the *value*.
+        Example: 'DEADBEEF'.
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
-        )
-    defaultBinValue = defaultHexValue = base.noValue
-    encoding = 'us-ascii'
-    def __init__(self, value=None, tagSet=None, subtypeSpec=None,
-                 encoding=None, binValue=None, hexValue=None):
-        if encoding is None:
-            self._encoding = self.encoding
-        else:
-            self._encoding = encoding
-        if binValue is not None:
-            value = self.fromBinaryString(binValue)
-        if hexValue is not None:
-            value = self.fromHexString(hexValue)
-        if value is None or value is base.noValue:
-            value = self.defaultHexValue
-        if value is None or value is base.noValue:
-            value = self.defaultBinValue
-        self.__intValue = None
-        base.AbstractSimpleAsn1Item.__init__(self, value, tagSet, subtypeSpec)
-
-    def clone(self, value=None, tagSet=None, subtypeSpec=None,
-              encoding=None, binValue=None, hexValue=None):
-        if value is None and tagSet is None and subtypeSpec is None and \
-               encoding is None and binValue is None and hexValue is None:
-            return self
-        if value is None and binValue is None and hexValue is None:
-            value = self._value
-        if tagSet is None:
-            tagSet = self._tagSet
-        if subtypeSpec is None:
-            subtypeSpec = self._subtypeSpec
-        if encoding is None:
-            encoding = self._encoding
-        return self.__class__(
-            value, tagSet, subtypeSpec, encoding, binValue, hexValue
-            )
-   
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    # Optimization for faster codec lookup
+    typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+    defaultBinValue = defaultHexValue = noValue
+    encoding = 'iso-8859-1'
+
+    def __init__(self, value=noValue, **kwargs):
+        if kwargs:
+            if value is noValue or value is None:
+                try:
+                    value = self.fromBinaryString(kwargs.pop('binValue'))
+
+                except KeyError:
+                    pass
+
+                try:
+                    value = self.fromHexString(kwargs.pop('hexValue'))
+
+                except KeyError:
+                    pass
+
+        if value is noValue or value is None:
+            if self.defaultBinValue is not noValue:
+                value = self.fromBinaryString(self.defaultBinValue)
+
+            elif self.defaultHexValue is not noValue:
+                value = self.fromHexString(self.defaultHexValue)
+
+        if 'encoding' not in kwargs:
+            kwargs['encoding'] = self.encoding
+
+        base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value : :class:`str`, :class:`bytes` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+        encoding: :py:class:`str`
+            Unicode codec ID to encode/decode :class:`unicode` (Python 2)
+            or :class:`str` (Python 3) the payload when |ASN.1|
+            object is used in string context.
+
+        binValue: :py:class:`str`
+            Binary string initializer. Example: '10110011'.
+        
+        hexValue: :py:class:`str`
+            Hexadecimal string initializer. Example: 'DEADBEEF'.
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value : :class:`str`, :class:`bytes` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to |ASN.1| object tag set
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to |ASN.1| object tag set
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Add ASN.1 constraints object to one of the caller, then
+            use the result as new object's ASN.1 constraints.
+
+        encoding: :py:class:`str`
+            Unicode codec ID to encode/decode :class:`unicode` (Python 2)
+            or :class:`str` (Python 3) the payload when *OctetString*
+            object is used in string context.
+
+        binValue: :py:class:`str`
+            Binary string initializer. Example: '10110011'.
+        
+        hexValue: :py:class:`str`
+            Hexadecimal string initializer. Example: 'DEADBEEF'.
+
+        Returns
+        -------
+        :
+             new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
     if sys.version_info[0] <= 2:
         def prettyIn(self, value):
             if isinstance(value, str):
                 return value
+            elif isinstance(value, unicode):
+                try:
+                    return value.encode(self.encoding)
+                except (LookupError, UnicodeEncodeError):
+                    raise error.PyAsn1Error(
+                        "Can't encode string '%s' with codec %s" % (value, self.encoding)
+                    )
             elif isinstance(value, (tuple, list)):
                 try:
-                    return ''.join([ chr(x) for x in value ])
+                    return ''.join([chr(x) for x in value])
                 except ValueError:
                     raise error.PyAsn1Error(
-                        'Bad OctetString initializer \'%s\'' % (value,)
-                        )                
+                        'Bad %s initializer \'%s\'' % (self.__class__.__name__, value)
+                    )
             else:
                 return str(value)
+
+        def __str__(self):
+            return str(self._value)
+
+        def __unicode__(self):
+            try:
+                return self._value.decode(self.encoding)
+
+            except UnicodeDecodeError:
+                raise error.PyAsn1Error(
+                    "Can't decode string '%s' with codec %s" % (self._value, self.encoding)
+                )
+
+        def asOctets(self):
+            return str(self._value)
+
+        def asNumbers(self):
+            return tuple([ord(x) for x in self._value])
+
     else:
         def prettyIn(self, value):
             if isinstance(value, bytes):
                 return value
-            elif isinstance(value, OctetString):
-                return value.asOctets()
-            elif isinstance(value, (tuple, list, map)):
+            elif isinstance(value, str):
                 try:
-                    return bytes(value)
-                except ValueError:
-                    raise error.PyAsn1Error(
-                        'Bad OctetString initializer \'%s\'' % (value,)
-                        )
-            else:
-                try:
-                    return str(value).encode(self._encoding)
+                    return value.encode(self.encoding)
                 except UnicodeEncodeError:
                     raise error.PyAsn1Error(
-                        'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
-                        )
-                        
-
-    def fromBinaryString(self, value):
-        bitNo = 8; byte = 0; r = ()
-        for v in value:
-            if bitNo:
-                bitNo = bitNo - 1
-            else:
-                bitNo = 7
-                r = r + (byte,)
-                byte = 0
-            if v == '0':
-                v = 0
-            elif v == '1':
-                v = 1
+                        'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self.encoding)
+                    )
+            elif isinstance(value, OctetString):  # a shortcut, bytes() would work the same way
+                return value.asOctets()
+            elif isinstance(value, base.AbstractSimpleAsn1Item):  # this mostly targets Integer objects
+                return self.prettyIn(str(value))
+            elif isinstance(value, (tuple, list)):
+                return self.prettyIn(bytes(value))
             else:
+                return bytes(value)
+
+        def __str__(self):
+            try:
+                return self._value.decode(self.encoding)
+
+            except UnicodeDecodeError:
                 raise error.PyAsn1Error(
-                    'Non-binary OCTET STRING initializer %s' % (v,)
-                    )
-            byte = byte | (v << bitNo)
-        return octets.ints2octs(r + (byte,))
-        
-    def fromHexString(self, value):            
-        r = p = ()
-        for v in value:
-            if p:
-                r = r + (int(p+v, 16),)
-                p = ()
-            else:
-                p = v
-        if p:
-            r = r + (int(p+'0', 16),)
-        return octets.ints2octs(r)
+                    'Can\'t decode string \'%s\' with \'%s\' codec at \'%s\'' % (self._value, self.encoding, self.__class__.__name__)
+                )
+
+        def __bytes__(self):
+            return bytes(self._value)
+
+        def asOctets(self):
+            return bytes(self._value)
+
+        def asNumbers(self):
+            return tuple(self._value)
 
     def prettyOut(self, value):
         if sys.version_info[0] <= 2:
-            numbers = tuple([ ord(x) for x in value ])
+            numbers = tuple((ord(x) for x in value))
         else:
             numbers = tuple(value)
-        if [ x for x in numbers if x < 32 or x > 126 ]:
-            return '0x' + ''.join([ '%.2x' % x for x in numbers ])
+        for x in numbers:
+            if x < 32 or x > 126:
+                return '0x' + ''.join(('%.2x' % x for x in numbers))
         else:
-            return str(value)
+            try:
+                return value.decode(self.encoding)
+
+            except UnicodeDecodeError:
+                raise error.PyAsn1Error(
+                    "Can't decode string '%s' with '%s' codec at '%s'" % (value, self.encoding, self.__class__.__name__)
+                )
+
+    @staticmethod
+    def fromBinaryString(value):
+        """Create a |ASN.1| object initialized from a string of '0' and '1'.
+
+        Parameters
+        ----------
+        value: :class:`str`
+            Text string like '1010111'
+        """
+        bitNo = 8
+        byte = 0
+        r = []
+        for v in value:
+            if bitNo:
+                bitNo -= 1
+            else:
+                bitNo = 7
+                r.append(byte)
+                byte = 0
+            if v in ('0', '1'):
+                v = int(v)
+            else:
+                raise error.PyAsn1Error(
+                    'Non-binary OCTET STRING initializer %s' % (v,)
+                )
+            byte |= v << bitNo
+
+        r.append(byte)
+
+        return octets.ints2octs(r)
+
+    @staticmethod
+    def fromHexString(value):
+        """Create a |ASN.1| object initialized from the hex string.
+
+        Parameters
+        ----------
+        value: :class:`str`
+            Text string like 'DEADBEEF'
+        """
+        r = []
+        p = []
+        for v in value:
+            if p:
+                r.append(int(p + v, 16))
+                p = None
+            else:
+                p = v
+        if p:
+            r.append(int(p + '0', 16))
+
+        return octets.ints2octs(r)
 
     def __repr__(self):
-        if self._value is base.noValue:
-            return self.__class__.__name__ + '()'
-        if [ x for x in self.asNumbers() if x < 32 or x > 126 ]:
-            return self.__class__.__name__ + '(hexValue=\'' + ''.join([ '%.2x' % x for x in self.asNumbers() ])+'\')'
-        else:
-            return self.__class__.__name__ + '(\'' + self.prettyOut(self._value) + '\')'
-                                
-    if sys.version_info[0] <= 2:
-        def __str__(self): return str(self._value)
-        def __unicode__(self):
-            return self._value.decode(self._encoding, 'ignore')
-        def asOctets(self): return self._value
-        def asNumbers(self):
-            if self.__intValue is None:
-                self.__intValue = tuple([ ord(x) for x in self._value ])
-            return self.__intValue
-    else:
-        def __str__(self): return self._value.decode(self._encoding, 'ignore')
-        def __bytes__(self): return self._value
-        def asOctets(self): return self._value
-        def asNumbers(self):
-            if self.__intValue is None:
-                self.__intValue = tuple(self._value)
-            return self.__intValue
- 
+        r = []
+        doHex = False
+        if self._value is not self.defaultValue:
+            for x in self.asNumbers():
+                if x < 32 or x > 126:
+                    doHex = True
+                    break
+            if not doHex:
+                r.append('%r' % (self._value,))
+        if self.tagSet is not self.__class__.tagSet:
+            r.append('tagSet=%r' % (self.tagSet,))
+        if self.subtypeSpec is not self.__class__.subtypeSpec:
+            r.append('subtypeSpec=%r' % (self.subtypeSpec,))
+        if self.encoding is not self.__class__.encoding:
+            r.append('encoding=%r' % (self.encoding,))
+        if doHex:
+            r.append('hexValue=%r' % ''.join(['%.2x' % x for x in self.asNumbers()]))
+        return '%s(%s)' % (self.__class__.__name__, ', '.join(r))
+
     # Immutable sequence object protocol
-    
+
     def __len__(self):
-        if self._len is None:
-            self._len = len(self._value)
-        return self._len
+        return len(self._value)
+
     def __getitem__(self, i):
-        if isinstance(i, slice):
-            return self.clone(operator.getitem(self._value, i))
+        if i.__class__ is slice:
+            return self.clone(self._value[i])
         else:
             return self._value[i]
 
-    def __add__(self, value): return self.clone(self._value + self.prettyIn(value))
-    def __radd__(self, value): return self.clone(self.prettyIn(value) + self._value)
-    def __mul__(self, value): return self.clone(self._value * value)
-    def __rmul__(self, value): return self * value
+    def __iter__(self):
+        return iter(self._value)
+
+    def __contains__(self, value):
+        return value in self._value
+
+    def __add__(self, value):
+        return self.clone(self._value + self.prettyIn(value))
+
+    def __radd__(self, value):
+        return self.clone(self.prettyIn(value) + self._value)
+
+    def __mul__(self, value):
+        return self.clone(self._value * value)
+
+    def __rmul__(self, value):
+        return self * value
+
+    def __int__(self):
+        return int(self._value)
+
+    def __float__(self):
+        return float(self._value)
+
+    def __reversed__(self):
+        return reversed(self._value)
+
 
 class Null(OctetString):
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).
+
+    Parameters
+    ----------
+    value : :class:`str` or :py:class:`~pyasn1.type.univ.Null` object
+        Python empty string literal or *Null* class instance.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
     defaultValue = ''.encode()  # This is tightly constrained
-    tagSet = baseTagSet = tag.initTagSet(
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
-        )
-    subtypeSpec = OctetString.subtypeSpec+constraint.SingleValueConstraint(''.encode())
-    
+    )
+    subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
+
+    # Optimization for faster codec lookup
+    typeId = OctetString.getTypeId()
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of 
+            inheriting one from the caller.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.univ.Null`
+            new instance of NULL type/value
+        """
+        return OctetString.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`int`, :class:`str` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.univ.Null`
+            new instance of NULL type/value
+        """
+        return OctetString.subtype(self, value, **kwargs)
+
+
 if sys.version_info[0] <= 2:
     intTypes = (int, long)
 else:
-    intTypes = int
+    intTypes = (int,)
+
+numericTypes = intTypes + (float,)
+
 
 class ObjectIdentifier(base.AbstractSimpleAsn1Item):
-    tagSet = baseTagSet = tag.initTagSet(
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).
+
+    Parameters
+    ----------
+    value: :class:`tuple`, :class:`str` or |ASN.1| object
+        Python sequence of :class:`int` or string literal or |ASN.1| object.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+    """
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
-        )
-    def __add__(self, other): return self.clone(self._value + other)
-    def __radd__(self, other): return self.clone(other + self._value)
-
-    def asTuple(self): return self._value
-    
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    # Optimization for faster codec lookup
+    typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+    def __add__(self, other):
+        return self.clone(self._value + other)
+
+    def __radd__(self, other):
+        return self.clone(other + self._value)
+
+    def asTuple(self):
+        return self._value
+
     # Sequence object protocol
-    
+
     def __len__(self):
-        if self._len is None:
-            self._len = len(self._value)
-        return self._len
+        return len(self._value)
+
     def __getitem__(self, i):
-        if isinstance(i, slice):
-            return self.clone(
-                operator.getitem(self._value, i)
-                )
+        if i.__class__ is slice:
+            return self.clone(self._value[i])
         else:
             return self._value[i]
 
-    def __str__(self): return self.prettyPrint()
-    
-    def index(self, suboid): return self._value.index(suboid)
-
-    def isPrefixOf(self, value):
-        """Returns true if argument OID resides deeper in the OID tree"""
+    def __iter__(self):
+        return iter(self._value)
+
+    def __contains__(self, value):
+        return value in self._value
+
+    def __str__(self):
+        return self.prettyPrint()
+
+    def __repr__(self):
+        return '%s(%r)' % (self.__class__.__name__, self.prettyPrint())
+
+    def index(self, suboid):
+        return self._value.index(suboid)
+
+    def isPrefixOf(self, other):
+        """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
+
+        Parameters
+        ----------
+        other: |ASN.1| object
+            |ASN.1| object
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
+            or :class:`False` otherwise.
+        """
         l = len(self)
-        if l <= len(value):
-            if self._value[:l] == value[:l]:
-                return 1
-        return 0
+        if l <= len(other):
+            if self._value[:l] == other[:l]:
+                return True
+        return False
 
     def prettyIn(self, value):
-        """Dotted -> tuple of numerics OID converter"""
-        if isinstance(value, tuple):
-            pass
-        elif isinstance(value, ObjectIdentifier):
-            return tuple(value)        
-        elif isinstance(value, str):
-            r = []
-            for element in [ x for x in value.split('.') if x != '' ]:
-                try:
-                    r.append(int(element, 0))
-                except ValueError:
-                    raise error.PyAsn1Error(
-                        'Malformed Object ID %s at %s: %s' %
-                        (str(value), self.__class__.__name__, sys.exc_info()[1])
-                        )
-            value = tuple(r)
-        else:
+        if isinstance(value, ObjectIdentifier):
+            return tuple(value)
+        elif octets.isStringType(value):
+            if '-' in value:
+                raise error.PyAsn1Error(
+                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+                )
             try:
-                value = tuple(value)
-            except TypeError:
+                return tuple([int(subOid) for subOid in value.split('.') if subOid])
+            except ValueError:
                 raise error.PyAsn1Error(
-                        'Malformed Object ID %s at %s: %s' %
-                        (str(value), self.__class__.__name__,sys.exc_info()[1])
-                        )
-
-        for x in value:
-            if not isinstance(x, intTypes) or x < 0:
-                raise error.PyAsn1Error(
-                    'Invalid sub-ID in %s at %s' % (value, self.__class__.__name__)
-                    )
-    
-        return value
-
-    def prettyOut(self, value): return '.'.join([ str(x) for x in value ])
-    
+                    'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+                )
+
+        try:
+            tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
+
+        except (ValueError, TypeError):
+            raise error.PyAsn1Error(
+                'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
+            )
+
+        if len(tupleOfInts) == len(value):
+            return tupleOfInts
+
+        raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
+
+    def prettyOut(self, value):
+        return '.'.join([str(x) for x in value])
+
+
 class Real(base.AbstractSimpleAsn1Item):
+    """Create |ASN.1| type or object.
+
+    |ASN.1| objects are immutable and duck-type Python :class:`float` objects.
+    Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
+    elements are mantissa, base and exponent.
+
+    Parameters
+    ----------
+    value: :class:`tuple`, :class:`float` or |ASN.1| object
+        Python sequence of :class:`int` (representing mantissa, base and
+        exponent) or float instance or *Real* class instance.
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    Raises
+    ------
+    : :py:class:`pyasn1.error.PyAsn1Error`
+        On constraint violation or bad initializer.
+
+    """
+    binEncBase = None  # binEncBase = 16 is recommended for large numbers
+
     try:
         _plusInf = float('inf')
         _minusInf = float('-inf')
         _inf = (_plusInf, _minusInf)
     except ValueError:
         # Infinity support is platform and Python dependent
         _plusInf = _minusInf = None
         _inf = ()
 
-    tagSet = baseTagSet = tag.initTagSet(
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
-        )
-
-    def __normalizeBase10(self, value):
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    # Optimization for faster codec lookup
+    typeId = base.AbstractSimpleAsn1Item.getTypeId()
+
+    def clone(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *clone()* method will replace corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`tuple`, :class:`float` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tag(s) to use in new object instead of inheriting from the caller
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+            Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.clone(self, value, **kwargs)
+
+    def subtype(self, value=noValue, **kwargs):
+        """Create a copy of a |ASN.1| type or object.
+
+        Any parameters to the *subtype()* method will be added to the corresponding
+        properties of the |ASN.1| object.
+
+        Parameters
+        ----------
+        value: :class:`tuple`, :class:`float` or |ASN.1| object
+            Initialization value to pass to new ASN.1 object instead of
+            inheriting one from the caller.
+
+        implicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Implicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        explicitTag: :py:class:`~pyasn1.type.tag.Tag`
+            Explicitly apply given ASN.1 tag object to caller's 
+            :py:class:`~pyasn1.type.tag.TagSet`, then use the result as
+            new object's ASN.1 tag(s).
+
+        subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+             Object representing ASN.1 subtype constraint(s) to use in new object instead of inheriting from the caller
+
+        Returns
+        -------
+        :
+            new instance of |ASN.1| type/value
+        """
+        return base.AbstractSimpleAsn1Item.subtype(self, value, **kwargs)
+
+    @staticmethod
+    def __normalizeBase10(value):
         m, b, e = value
         while m and m % 10 == 0:
-            m = m / 10
-            e = e + 1
+            m /= 10
+            e += 1
         return m, b, e
 
     def prettyIn(self, value):
         if isinstance(value, tuple) and len(value) == 3:
-            for d in value:
-                if not isinstance(d, intTypes):
-                    raise error.PyAsn1Error(
-                        'Lame Real value syntax: %s' % (value,)
-                        )
+            if not isinstance(value[0], numericTypes) or \
+                    not isinstance(value[1], intTypes) or \
+                    not isinstance(value[2], intTypes):
+                raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
+            if isinstance(value[0], float) and \
+                    self._inf and value[0] in self._inf:
+                return value[0]
             if value[1] not in (2, 10):
                 raise error.PyAsn1Error(
                     'Prohibited base for Real value: %s' % (value[1],)
-                    )
+                )
             if value[1] == 10:
                 value = self.__normalizeBase10(value)
             return value
         elif isinstance(value, intTypes):
             return self.__normalizeBase10((value, 10, 0))
-        elif isinstance(value, float):
+        elif isinstance(value, float) or octets.isStringType(value):
+            if octets.isStringType(value):
+                try:
+                    value = float(value)
+                except ValueError:
+                    raise error.PyAsn1Error(
+                        'Bad real value syntax: %s' % (value,)
+                    )
             if self._inf and value in self._inf:
                 return value
             else:
                 e = 0
                 while int(value) != value:
-                    value = value * 10
-                    e = e - 1
+                    value *= 10
+                    e -= 1
                 return self.__normalizeBase10((int(value), 10, e))
         elif isinstance(value, Real):
             return tuple(value)
-        elif isinstance(value, str):  # handle infinite literal
-            try:
-                return float(value)
-            except ValueError:
-                pass
         raise error.PyAsn1Error(
             'Bad real value syntax: %s' % (value,)
-            )
-        
+        )
+
     def prettyOut(self, value):
         if value in self._inf:
             return '\'%s\'' % value
         else:
             return str(value)
 
-    def isPlusInfinity(self): return self._value == self._plusInf
-    def isMinusInfinity(self): return self._value == self._minusInf
-    def isInfinity(self): return self._value in self._inf
-    
-    def __str__(self): return str(float(self))
-    
-    def __add__(self, value): return self.clone(float(self) + value)
-    def __radd__(self, value): return self + value
-    def __mul__(self, value): return self.clone(float(self) * value)
-    def __rmul__(self, value): return self * value
-    def __sub__(self, value): return self.clone(float(self) - value)
-    def __rsub__(self, value): return self.clone(value - float(self))
-    def __mod__(self, value): return self.clone(float(self) % value)
-    def __rmod__(self, value): return self.clone(value % float(self))
-    def __pow__(self, value, modulo=None): return self.clone(pow(float(self), value, modulo))
-    def __rpow__(self, value): return self.clone(pow(value, float(self)))
+    def prettyPrint(self, scope=0):
+        if self.isInf:
+            return self.prettyOut(self._value)
+        else:
+            try:
+                return str(float(self))
+
+            except OverflowError:
+                return '<overflow>'
+
+    @property
+    def isPlusInf(self):
+        """Indicate PLUS-INFINITY object value
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if calling object represents plus infinity
+            or :class:`False` otherwise.
+
+        """
+        return self._value == self._plusInf
+
+    @property
+    def isMinusInf(self):
+        """Indicate MINUS-INFINITY object value
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if calling object represents minus infinity
+            or :class:`False` otherwise.
+        """
+        return self._value == self._minusInf
+
+    @property
+    def isInf(self):
+        return self._value in self._inf
+
+    def __str__(self):
+        return str(float(self))
+
+    def __add__(self, value):
+        return self.clone(float(self) + value)
+
+    def __radd__(self, value):
+        return self + value
+
+    def __mul__(self, value):
+        return self.clone(float(self) * value)
+
+    def __rmul__(self, value):
+        return self * value
+
+    def __sub__(self, value):
+        return self.clone(float(self) - value)
+
+    def __rsub__(self, value):
+        return self.clone(value - float(self))
+
+    def __mod__(self, value):
+        return self.clone(float(self) % value)
+
+    def __rmod__(self, value):
+        return self.clone(value % float(self))
+
+    def __pow__(self, value, modulo=None):
+        return self.clone(pow(float(self), value, modulo))
+
+    def __rpow__(self, value):
+        return self.clone(pow(value, float(self)))
 
     if sys.version_info[0] <= 2:
-        def __div__(self, value): return self.clone(float(self) / value)
-        def __rdiv__(self, value): return self.clone(value / float(self))
+        def __div__(self, value):
+            return self.clone(float(self) / value)
+
+        def __rdiv__(self, value):
+            return self.clone(value / float(self))
     else:
-        def __truediv__(self, value): return self.clone(float(self) / value)
-        def __rtruediv__(self, value): return self.clone(value / float(self))
-        def __divmod__(self, value): return self.clone(float(self) // value)
-        def __rdivmod__(self, value): return self.clone(value // float(self))
-
-    def __int__(self): return int(float(self))
+        def __truediv__(self, value):
+            return self.clone(float(self) / value)
+
+        def __rtruediv__(self, value):
+            return self.clone(value / float(self))
+
+        def __divmod__(self, value):
+            return self.clone(float(self) // value)
+
+        def __rdivmod__(self, value):
+            return self.clone(value // float(self))
+
+    def __int__(self):
+        return int(float(self))
+
     if sys.version_info[0] <= 2:
-        def __long__(self): return long(float(self))
+        def __long__(self):
+            return long(float(self))
+
     def __float__(self):
         if self._value in self._inf:
             return self._value
         else:
             return float(
                 self._value[0] * pow(self._value[1], self._value[2])
-                )
-    def __abs__(self): return abs(float(self))
-
-    def __lt__(self, value): return float(self) < value
-    def __le__(self, value): return float(self) <= value
-    def __eq__(self, value): return float(self) == value
-    def __ne__(self, value): return float(self) != value
-    def __gt__(self, value): return float(self) > value
-    def __ge__(self, value): return float(self) >= value
+            )
+
+    def __abs__(self):
+        return self.clone(abs(float(self)))
+
+    def __pos__(self):
+        return self.clone(+float(self))
+
+    def __neg__(self):
+        return self.clone(-float(self))
+
+    def __round__(self, n=0):
+        r = round(float(self), n)
+        if n:
+            return self.clone(r)
+        else:
+            return r
+
+    def __floor__(self):
+        return self.clone(math.floor(float(self)))
+
+    def __ceil__(self):
+        return self.clone(math.ceil(float(self)))
+
+    if sys.version_info[0:2] > (2, 5):
+        def __trunc__(self):
+            return self.clone(math.trunc(float(self)))
+
+    def __lt__(self, value):
+        return float(self) < value
+
+    def __le__(self, value):
+        return float(self) <= value
+
+    def __eq__(self, value):
+        return float(self) == value
+
+    def __ne__(self, value):
+        return float(self) != value
+
+    def __gt__(self, value):
+        return float(self) > value
+
+    def __ge__(self, value):
+        return float(self) >= value
 
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(float(self))
+        def __nonzero__(self):
+            return bool(float(self))
     else:
-        def __bool__(self): return bool(float(self))
+        def __bool__(self):
+            return bool(float(self))
+
         __hash__ = base.AbstractSimpleAsn1Item.__hash__
 
     def __getitem__(self, idx):
         if self._value in self._inf:
             raise error.PyAsn1Error('Invalid infinite value operation')
         else:
             return self._value[idx]
-    
+
+    # compatibility stubs
+
+    def isPlusInfinity(self):
+        return self.isPlusInf
+
+    def isMinusInfinity(self):
+        return self.isMinusInf
+
+    def isInfinity(self):
+        return self.isInf
+
+
 class Enumerated(Integer):
-    tagSet = baseTagSet = tag.initTagSet(
+    __doc__ = Integer.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
-        )
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    # Optimization for faster codec lookup
+    typeId = Integer.getTypeId()
+
+    #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
+    #: representing symbolic aliases for numbers
+    namedValues = namedval.NamedValues()
+
 
 # "Structured" ASN.1 types
 
-class SetOf(base.AbstractConstructedAsn1Item):
-    componentType = None
-    tagSet = baseTagSet = tag.initTagSet(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
-        )
-    typeId = 1
+class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
+    """Create |ASN.1| type.
+
+    |ASN.1| objects are mutable and duck-type Python :class:`list` objects.
+
+    Parameters
+    ----------
+    componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+        A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing collection size constraint
+     """
+
+    def __init__(self, *args, **kwargs):
+        # support positional params for backward compatibility
+        if args:
+            for key, value in zip(('componentType', 'tagSet',
+                                   'subtypeSpec', 'sizeSpec'), args):
+                if key in kwargs:
+                    raise error.PyAsn1Error('Conflicting positional and keyword params!')
+                kwargs['componentType'] = value
+
+        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
+
+    # Python list protocol
+
+    def __getitem__(self, idx):
+        try:
+            return self.getComponentByPosition(idx)
+
+        except error.PyAsn1Error:
+            raise IndexError(sys.exc_info()[1])
+
+    def __setitem__(self, idx, value):
+        try:
+            self.setComponentByPosition(idx, value)
+
+        except error.PyAsn1Error:
+            raise IndexError(sys.exc_info()[1])
+
+    def clear(self):
+        self._componentValues = []
+
+    def append(self, value):
+        self[len(self)] = value
+
+    def count(self, value):
+        return self._componentValues.count(value)
+
+    def extend(self, values):
+        for value in values:
+            self.append(value)
+
+    def index(self, value, start=0, stop=None):
+        if stop is None:
+            stop = len(self)
+        try:
+            return self._componentValues.index(value, start, stop)
+
+        except error.PyAsn1Error:
+            raise ValueError(sys.exc_info()[1])
+
+    def reverse(self):
+        self._componentValues.reverse()
+
+    def sort(self, key=None, reverse=False):
+        self._componentValues.sort(key=key, reverse=reverse)
+
+    def __iter__(self):
+        return iter(self._componentValues)
 
     def _cloneComponentValues(self, myClone, cloneValueFlag):
-        idx = 0; l = len(self._componentValues)
-        while idx < l:
-            c = self._componentValues[idx]
-            if c is not None:
-                if isinstance(c, base.AbstractConstructedAsn1Item):
+        for idx, componentValue in enumerate(self._componentValues):
+            if componentValue is not noValue:
+                if isinstance(componentValue, base.AbstractConstructedAsn1Item):
                     myClone.setComponentByPosition(
-                        idx, c.clone(cloneValueFlag=cloneValueFlag)
-                        )
+                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
+                    )
                 else:
-                    myClone.setComponentByPosition(idx, c.clone())
-            idx = idx + 1
-        
-    def _verifyComponent(self, idx, value):
-        if self._componentType is not None and \
-               not self._componentType.isSuperTypeOf(value):
-            raise error.PyAsn1Error('Component type error %s' % (value,))
-
-    def getComponentByPosition(self, idx): return self._componentValues[idx]
-    def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
-        l = len(self._componentValues)
-        if idx >= l:
-            self._componentValues = self._componentValues + (idx-l+1)*[None]
-        if value is None:
-            if self._componentValues[idx] is None:
-                if self._componentType is None:
-                    raise error.PyAsn1Error('Component type not defined')
-                self._componentValues[idx] = self._componentType.clone()
-                self._componentValuesSet = self._componentValuesSet + 1
-            return self
-        elif not isinstance(value, base.Asn1Item):
-            if self._componentType is None:
-                raise error.PyAsn1Error('Component type not defined')
-            if isinstance(self._componentType, base.AbstractSimpleAsn1Item):
-                value = self._componentType.clone(value=value)
-            else:
-                raise error.PyAsn1Error('Instance value required')
-        if verifyConstraints:
-            if self._componentType is not None:
-                self._verifyComponent(idx, value)
-            self._verifySubtypeSpec(value, idx)            
-        if self._componentValues[idx] is None:
-            self._componentValuesSet = self._componentValuesSet + 1
-        self._componentValues[idx] = value
-        return self
-
-    def getComponentTagMap(self):
-        if self._componentType is not None:
-            return self._componentType.getTagMap()
-
-    def prettyPrint(self, scope=0):
-        scope = scope + 1
-        r = self.__class__.__name__ + ':\n'        
-        for idx in range(len(self._componentValues)):
-            r = r + ' '*scope
-            if self._componentValues[idx] is None:
-                r = r + '<empty>'
-            else:
-                r = r + self._componentValues[idx].prettyPrint(scope)
-        return r
-
-class SequenceOf(SetOf):
-    tagSet = baseTagSet = tag.initTagSet(
-        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
-        )
-    typeId = 2
-
-class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
-    componentType = namedtype.NamedTypes()
-    def __init__(self, componentType=None, tagSet=None,
-                 subtypeSpec=None, sizeSpec=None):
-        base.AbstractConstructedAsn1Item.__init__(
-            self, componentType, tagSet, subtypeSpec, sizeSpec
-            )
-        if self._componentType is None:
-            self._componentTypeLen = 0
-        else:
-            self._componentTypeLen = len(self._componentType)
-
-    def __getitem__(self, idx):
-        if isinstance(idx, str):
-            return self.getComponentByName(idx)
-        else:
-            return base.AbstractConstructedAsn1Item.__getitem__(self, idx)
-
-    def __setitem__(self, idx, value):
-        if isinstance(idx, str):
-            self.setComponentByName(idx, value)
-        else:
-            base.AbstractConstructedAsn1Item.__setitem__(self, idx, value)
-        
-    def _cloneComponentValues(self, myClone, cloneValueFlag):
-        idx = 0; l = len(self._componentValues)
-        while idx < l:
-            c = self._componentValues[idx]
-            if c is not None:
-                if isinstance(c, base.AbstractConstructedAsn1Item):
-                    myClone.setComponentByPosition(
-                        idx, c.clone(cloneValueFlag=cloneValueFlag)
-                        )
-                else:
-                    myClone.setComponentByPosition(idx, c.clone())
-            idx = idx + 1
-
-    def _verifyComponent(self, idx, value):
-        if idx >= self._componentTypeLen:
-            raise error.PyAsn1Error(
-                'Component type error out of range'
-                )
-        t = self._componentType[idx].getType()
-        if not t.isSuperTypeOf(value):
-            raise error.PyAsn1Error('Component type error %r vs %r' % (t, value))
-
-    def getComponentByName(self, name):
-        return self.getComponentByPosition(
-            self._componentType.getPositionByName(name)
-            )
-    def setComponentByName(self, name, value=None, verifyConstraints=True):
-        return self.setComponentByPosition(
-            self._componentType.getPositionByName(name), value,
-            verifyConstraints
-            )
+                    myClone.setComponentByPosition(idx, componentValue.clone())
 
     def getComponentByPosition(self, idx):
+        """Return |ASN.1| type component value by position.
+
+        Equivalent to Python sequence subscription operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        idx : :class:`int`
+            Component index (zero-based). Must either refer to an existing
+            component or to N+1 component (if *componentType* is set). In the latter
+            case a new component type gets instantiated and appended to the |ASN.1|
+            sequence.
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.base.PyAsn1Item`
+            a pyasn1 object
+        """
         try:
             return self._componentValues[idx]
         except IndexError:
-            if idx < self._componentTypeLen:
-                return
-            raise
-    def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
-        l = len(self._componentValues)
-        if idx >= l:
-            self._componentValues = self._componentValues + (idx-l+1)*[None]
-        if value is None:
-            if self._componentValues[idx] is None:
-                self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
-                self._componentValuesSet = self._componentValuesSet + 1
-            return self
+            self.setComponentByPosition(idx)
+            return self._componentValues[idx]
+
+    def setComponentByPosition(self, idx, value=noValue,
+                               verifyConstraints=True,
+                               matchTags=True,
+                               matchConstraints=True):
+        """Assign |ASN.1| type component by position.
+
+        Equivalent to Python sequence item assignment operation (e.g. `[]`)
+        or list.append() (when idx == len(self)).
+
+        Parameters
+        ----------
+        idx: :class:`int`
+            Component index (zero-based). Must either refer to existing
+            component or to N+1 component. In the latter case a new component
+            type gets instantiated (if *componentType* is set, or given ASN.1
+            object is taken otherwise) and appended to the |ASN.1| sequence.
+
+        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+            A Python value to initialize |ASN.1| component with (if *componentType* is set)
+            or ASN.1 value object to assign to |ASN.1| component.
+
+        verifyConstraints: :class:`bool`
+             If `False`, skip constraints validation
+
+        matchTags: :class:`bool`
+             If `False`, skip component tags matching
+
+        matchConstraints: :class:`bool`
+             If `False`, skip component constraints matching
+
+        Returns
+        -------
+        self
+
+        Raises
+        ------
+        IndexError:
+            When idx > len(self)
+        """
+        if value is None:  # backward compatibility
+            value = noValue
+
+        componentType = self.componentType
+
+        try:
+            currentValue = self._componentValues[idx]
+        except IndexError:
+            currentValue = noValue
+
+            if len(self._componentValues) < idx:
+                raise error.PyAsn1Error('Component index out of range')
+
+        if value is noValue:
+            if componentType is not None:
+                value = componentType.clone()
+            elif currentValue is noValue:
+                raise error.PyAsn1Error('Component type not defined')
         elif not isinstance(value, base.Asn1Item):
-            t = self._componentType.getTypeByPosition(idx)
-            if isinstance(t, base.AbstractSimpleAsn1Item):
-                value = t.clone(value=value)
+            if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):
+                value = componentType.clone(value=value)
+            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
+                value = currentValue.clone(value=value)
+            else:
+                raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))
+        elif componentType is not None:
+            if self.strictConstraints:
+                if not componentType.isSameTypeWith(value, matchTags, matchConstraints):
+                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+            else:
+                if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):
+                    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+
+        if verifyConstraints and value.isValue:
+            try:
+                self.subtypeSpec(value, idx)
+
+            except error.PyAsn1Error:
+                exType, exValue, exTb = sys.exc_info()
+                raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
+        if currentValue is noValue:
+            self._componentValues.append(value)
+        else:
+            self._componentValues[idx] = value
+
+        return self
+
+    @property
+    def componentTagMap(self):
+        if self.componentType is not None:
+            return self.componentType.tagMap
+
+    def prettyPrint(self, scope=0):
+        scope += 1
+        representation = self.__class__.__name__ + ':\n'
+        for idx, componentValue in enumerate(self._componentValues):
+            representation += ' ' * scope
+            if (componentValue is noValue and
+                    self.componentType is not None):
+                representation += '<empty>'
             else:
-                raise error.PyAsn1Error('Instance value required')
-        if verifyConstraints:
+                representation += componentValue.prettyPrint(scope)
+        return representation
+
+    def prettyPrintType(self, scope=0):
+        scope += 1
+        representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
+        if self.componentType is not None:
+            representation += ' ' * scope
+            representation += self.componentType.prettyPrintType(scope)
+        return representation + '\n' + ' ' * (scope - 1) + '}'
+
+
+    @property
+    def isValue(self):
+        """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+        In other words, if *isValue* is `True`, then the ASN.1 object is
+        initialized.
+
+        For the purpose of this check, empty |ASN.1| object is considered
+        as initialized.
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if object represents ASN.1 value and type,
+            :class:`False` if object represents just ASN.1 type.
+
+        Note
+        ----
+        There is an important distinction between PyASN1 type and value objects.
+        The PyASN1 type objects can only participate in ASN.1 type
+        operations (subtyping, comparison etc) and serve as a
+        blueprint for serialization codecs to resolve ambiguous types.
+
+        The PyASN1 value objects can additionally participate in most
+        of built-in Python operations.
+        """
+        for componentValue in self._componentValues:
+            if not componentValue.isValue:
+                return False
+
+        return True
+
+
+class SequenceOf(SequenceOfAndSetOfBase):
+    __doc__ = SequenceOfAndSetOfBase.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+    )
+
+    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+    #: object representing ASN.1 type allowed within |ASN.1| type
+    componentType = None
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing size constraint on |ASN.1| objects
+    sizeSpec = constraint.ConstraintsIntersection()
+
+    # Disambiguation ASN.1 types identification
+    typeId = SequenceOfAndSetOfBase.getTypeId()
+
+
+class SetOf(SequenceOfAndSetOfBase):
+    __doc__ = SequenceOfAndSetOfBase.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+    )
+
+    #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+    #: object representing ASN.1 type allowed within |ASN.1| type
+    componentType = None
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing size constraint on |ASN.1| objects
+    sizeSpec = constraint.ConstraintsIntersection()
+
+    # Disambiguation ASN.1 types identification
+    typeId = SequenceOfAndSetOfBase.getTypeId()
+
+
+class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
+    """Create |ASN.1| type.
+
+    |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
+
+    Parameters
+    ----------
+    componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
+        Object holding named ASN.1 types allowed within this collection
+
+    tagSet: :py:class:`~pyasn1.type.tag.TagSet`
+        Object representing non-default ASN.1 tag(s)
+
+    subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing non-default ASN.1 subtype constraint(s)
+
+    sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+        Object representing collection size constraint
+    """
+    #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
+    #: object representing named ASN.1 types allowed within |ASN.1| type
+    componentType = namedtype.NamedTypes()
+
+
+    class DynamicNames(object):
+        """Fields names/positions mapping for component-less objects"""
+        def __init__(self):
+            self._keyToIdxMap = {}
+            self._idxToKeyMap = {}
+
+        def __len__(self):
+            return len(self._keyToIdxMap)
+
+        def __contains__(self, item):
+            return item in self._keyToIdxMap or item in self._idxToKeyMap
+
+        def __iter__(self):
+            return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
+
+        def __getitem__(self, item):
+            try:
+                return self._keyToIdxMap[item]
+
+            except KeyError:
+                return self._idxToKeyMap[item]
+
+        def getNameByPosition(self, idx):
+            try:
+                return self._idxToKeyMap[idx]
+
+            except KeyError:
+                raise error.PyAsn1Error('Type position out of range')
+
+        def getPositionByName(self, name):
+            try:
+                return self._keyToIdxMap[name]
+
+            except KeyError:
+                raise error.PyAsn1Error('Name %s not found' % (name,))
+
+        def addField(self, idx):
+            self._keyToIdxMap['field-%d' % idx] = idx
+            self._idxToKeyMap[idx] = 'field-%d' % idx
+
+
+    def __init__(self, **kwargs):
+        base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
+        self._componentTypeLen = len(self.componentType)
+        self._dynamicNames = self._componentTypeLen or self.DynamicNames()
+
+    def __getitem__(self, idx):
+        if octets.isStringType(idx):
+            try:
+                return self.getComponentByName(idx)
+
+            except error.PyAsn1Error:
+                # duck-typing dict
+                raise KeyError(sys.exc_info()[1])
+
+        else:
+            try:
+                return self.getComponentByPosition(idx)
+
+            except error.PyAsn1Error:
+                # duck-typing list
+                raise IndexError(sys.exc_info()[1])
+
+    def __setitem__(self, idx, value):
+        if octets.isStringType(idx):
+            try:
+                self.setComponentByName(idx, value)
+
+            except error.PyAsn1Error:
+                # duck-typing dict
+                raise KeyError(sys.exc_info()[1])
+
+        else:
+            try:
+                self.setComponentByPosition(idx, value)
+
+            except error.PyAsn1Error:
+                # duck-typing list
+                raise IndexError(sys.exc_info()[1])
+
+    def __contains__(self, key):
+        if self._componentTypeLen:
+            return key in self.componentType
+        else:
+            return key in self._dynamicNames
+
+    def __iter__(self):
+        return iter(self.componentType or self._dynamicNames)
+
+    # Python dict protocol
+
+    def values(self):
+        for idx in range(self._componentTypeLen or len(self._dynamicNames)):
+            yield self[idx]
+
+    def keys(self):
+        return iter(self)
+
+    def items(self):
+        for idx in range(self._componentTypeLen or len(self._dynamicNames)):
             if self._componentTypeLen:
-                self._verifyComponent(idx, value)
-            self._verifySubtypeSpec(value, idx)            
-        if self._componentValues[idx] is None:
-            self._componentValuesSet = self._componentValuesSet + 1
-        self._componentValues[idx] = value
+                yield self.componentType[idx].name, self[idx]
+            else:
+                yield self._dynamicNames[idx], self[idx]
+
+    def update(self, *iterValue, **mappingValue):
+        for k, v in iterValue:
+            self[k] = v
+        for k in mappingValue:
+            self[k] = mappingValue[k]
+
+    def clear(self):
+        self._componentValues = []
+        self._dynamicNames = self.DynamicNames()
+
+    def _cloneComponentValues(self, myClone, cloneValueFlag):
+        for idx, componentValue in enumerate(self._componentValues):
+            if componentValue is not noValue:
+                if isinstance(componentValue, base.AbstractConstructedAsn1Item):
+                    myClone.setComponentByPosition(
+                        idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
+                    )
+                else:
+                    myClone.setComponentByPosition(idx, componentValue.clone())
+
+    def getComponentByName(self, name):
+        """Returns |ASN.1| type component by name.
+
+        Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        name : :class:`str`
+            |ASN.1| type component name
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.base.PyAsn1Item`
+            Instantiate |ASN.1| component type or return existing component value
+        """
+        if self._componentTypeLen:
+            idx = self.componentType.getPositionByName(name)
+        else:
+            try:
+                idx = self._dynamicNames.getPositionByName(name)
+
+            except KeyError:
+                raise error.PyAsn1Error('Name %s not found' % (name,))
+
+        return self.getComponentByPosition(idx)
+
+    def setComponentByName(self, name, value=noValue,
+                           verifyConstraints=True,
+                           matchTags=True,
+                           matchConstraints=True):
+        """Assign |ASN.1| type component by name.
+
+        Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        name: :class:`str`
+            |ASN.1| type component name
+
+        value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+            A Python value to initialize |ASN.1| component with (if *componentType* is set)
+            or ASN.1 value object to assign to |ASN.1| component.
+
+        verifyConstraints: :class:`bool`
+             If `False`, skip constraints validation
+
+        matchTags: :class:`bool`
+             If `False`, skip component tags matching
+
+        matchConstraints: :class:`bool`
+             If `False`, skip component constraints matching
+
+        Returns
+        -------
+        self
+        """
+        if self._componentTypeLen:
+            idx = self.componentType.getPositionByName(name)
+        else:
+            try:
+                idx = self._dynamicNames.getPositionByName(name)
+
+            except KeyError:
+                raise error.PyAsn1Error('Name %s not found' % (name,))
+
+        return self.setComponentByPosition(
+            idx, value, verifyConstraints, matchTags, matchConstraints
+        )
+
+    def getComponentByPosition(self, idx):
+        """Returns |ASN.1| type component by index.
+
+        Equivalent to Python sequence subscription operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        idx : :class:`int`
+            Component index (zero-based). Must either refer to an existing
+            component or (if *componentType* is set) new ASN.1 type object gets
+            instantiated.
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.base.PyAsn1Item`
+            a PyASN1 object
+        """
+        try:
+            componentValue = self._componentValues[idx]
+        except IndexError:
+            componentValue = noValue
+
+        if componentValue is noValue:
+            self.setComponentByPosition(idx)
+
+        return self._componentValues[idx]
+
+    def setComponentByPosition(self, idx, value=noValue,
+                               verifyConstraints=True,
+                               matchTags=True,
+                               matchConstraints=True):
+        """Assign |ASN.1| type component by position.
+
+        Equivalent to Python sequence item assignment operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        idx : :class:`int`
+            Component index (zero-based). Must either refer to existing
+            component (if *componentType* is set) or to N+1 component
+            otherwise. In the latter case a new component of given ASN.1
+            type gets instantiated and appended to |ASN.1| sequence.
+
+        value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+            A Python value to initialize |ASN.1| component with (if *componentType* is set)
+            or ASN.1 value object to assign to |ASN.1| component.
+
+        verifyConstraints : :class:`bool`
+             If `False`, skip constraints validation
+
+        matchTags: :class:`bool`
+             If `False`, skip component tags matching
+
+        matchConstraints: :class:`bool`
+             If `False`, skip component constraints matching
+
+        Returns
+        -------
+        self
+        """
+        if value is None:  # backward compatibility
+            value = noValue
+
+        componentType = self.componentType
+        componentTypeLen = self._componentTypeLen
+
+        try:
+            currentValue = self._componentValues[idx]
+        except IndexError:
+            currentValue = noValue
+            if componentTypeLen:
+                if componentTypeLen < idx:
+                    raise error.PyAsn1Error('component index out of range')
+                self._componentValues = [noValue] * componentTypeLen
+
+        if value is noValue:
+            if componentTypeLen:
+                value = componentType.getTypeByPosition(idx).clone()
+            elif currentValue is noValue:
+                raise error.PyAsn1Error('Component type not defined')
+        elif not isinstance(value, base.Asn1Item):
+            if componentTypeLen:
+                subComponentType = componentType.getTypeByPosition(idx)
+                if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
+                    value = subComponentType.clone(value=value)
+                else:
+                    raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
+            elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
+                value = currentValue.clone(value=value)
+            else:
+                raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
+        elif (matchTags or matchConstraints) and componentTypeLen:
+            subComponentType = componentType.getTypeByPosition(idx)
+            if subComponentType is not noValue:
+                if self.strictConstraints:
+                    if not subComponentType.isSameTypeWith(value, matchTags, matchConstraints):
+                        raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+                else:
+                    if not subComponentType.isSuperTypeOf(value, matchTags, matchConstraints):
+                        raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
+
+        if verifyConstraints and value.isValue:
+            try:
+                self.subtypeSpec(value, idx)
+
+            except error.PyAsn1Error:
+                exType, exValue, exTb = sys.exc_info()
+                raise exType('%s at %s' % (exValue, self.__class__.__name__))
+
+        if componentTypeLen or idx in self._dynamicNames:
+            self._componentValues[idx] = value
+        elif len(self._componentValues) == idx:
+            self._componentValues.append(value)
+            self._dynamicNames.addField(idx)
+        else:
+            raise error.PyAsn1Error('Component index out of range')
+
         return self
 
-    def getNameByPosition(self, idx):
-        if self._componentTypeLen:
-            return self._componentType.getNameByPosition(idx)
-
-    def getDefaultComponentByPosition(self, idx):
-        if self._componentTypeLen and self._componentType[idx].isDefaulted:
-            return self._componentType[idx].getType()
+    @property
+    def isValue(self):
+        """Indicate if |ASN.1| object represents ASN.1 type or ASN.1 value.
+
+        In other words, if *isValue* is `True`, then the ASN.1 object is
+        initialized.
+
+        For the purpose of check, the *OPTIONAL* and *DEFAULT* fields are
+        unconditionally considered as initialized.
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if object represents ASN.1 value and type,
+            :class:`False` if object represents just ASN.1 type.
+
+        Note
+        ----
+        There is an important distinction between PyASN1 type and value objects.
+        The PyASN1 type objects can only participate in ASN.1 type
+        operations (subtyping, comparison etc) and serve as a
+        blueprint for serialization codecs to resolve ambiguous types.
+
+        The PyASN1 value objects can additionally participate in most
+        of built-in Python operations.
+        """
+        componentType = self.componentType
+
+        if componentType:
+            for idx, subComponentType in enumerate(componentType.namedTypes):
+                if subComponentType.isDefaulted or subComponentType.isOptional:
+                    continue
+                if (not self._componentValues or
+                        not self._componentValues[idx].isValue):
+                    return False
+
+        else:
+            for componentValue in self._componentValues:
+                if not componentValue.isValue:
+                    return False
+
+        return True
+
+    def prettyPrint(self, scope=0):
+        """Return an object representation string.
+
+        Returns
+        -------
+        : :class:`str`
+            Human-friendly object representation.
+        """
+        scope += 1
+        representation = self.__class__.__name__ + ':\n'
+        for idx, componentValue in enumerate(self._componentValues):
+            if componentValue is not noValue:
+                representation += ' ' * scope
+                if self.componentType:
+                    representation += self.componentType.getNameByPosition(idx)
+                else:
+                    representation += self._dynamicNames.getNameByPosition(idx)
+                representation = '%s=%s\n' % (
+                    representation, componentValue.prettyPrint(scope)
+                )
+        return representation
+
+    def prettyPrintType(self, scope=0):
+        scope += 1
+        representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
+        for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
+            representation += ' ' * scope
+            if self.componentType:
+                representation += '"%s"' % self.componentType.getNameByPosition(idx)
+            else:
+                representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
+            representation = '%s = %s\n' % (
+                representation, componentType.prettyPrintType(scope)
+            )
+        return representation + '\n' + ' ' * (scope - 1) + '}'
+
+    # backward compatibility
+
+    def setDefaultComponents(self):
+        return self
 
     def getComponentType(self):
         if self._componentTypeLen:
-            return self._componentType
-    
-    def setDefaultComponents(self):
-        if self._componentTypeLen == self._componentValuesSet:
-            return
-        idx = self._componentTypeLen
-        while idx:
-            idx = idx - 1
-            if self._componentType[idx].isDefaulted:
-                if self.getComponentByPosition(idx) is None:
-                    self.setComponentByPosition(idx)
-            elif not self._componentType[idx].isOptional:
-                if self.getComponentByPosition(idx) is None:
-                    raise error.PyAsn1Error(
-                        'Uninitialized component #%s at %r' % (idx, self)
-                        )
-
-    def prettyPrint(self, scope=0):
-        scope = scope + 1
-        r = self.__class__.__name__ + ':\n'
-        for idx in range(len(self._componentValues)):
-            if self._componentValues[idx] is not None:
-                r = r + ' '*scope
-                componentType = self.getComponentType()
-                if componentType is None:
-                    r = r + '<no-name>'
-                else:
-                    r = r + componentType.getNameByPosition(idx)
-                r = '%s=%s\n' % (
-                    r, self._componentValues[idx].prettyPrint(scope)
-                    )
-        return r
+            return self.componentType
+
+    def getNameByPosition(self, idx):
+        if self._componentTypeLen:
+            return self.componentType[idx].name
+
 
 class Sequence(SequenceAndSetBase):
-    tagSet = baseTagSet = tag.initTagSet(
+    __doc__ = SequenceAndSetBase.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
-        )
-    typeId = 3
+    )
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing constraints on |ASN.1| objects
+    sizeSpec = constraint.ConstraintsIntersection()
+
+    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+    #: object imposing size constraint on |ASN.1| objects
+    componentType = namedtype.NamedTypes()
+
+    # Disambiguation ASN.1 types identification
+    typeId = SequenceAndSetBase.getTypeId()
+
+    # backward compatibility
 
     def getComponentTagMapNearPosition(self, idx):
-        if self._componentType:
-            return self._componentType.getTagMapNearPosition(idx)
-    
+        if self.componentType:
+            return self.componentType.getTagMapNearPosition(idx)
+
     def getComponentPositionNearType(self, tagSet, idx):
-        if self._componentType:
-            return self._componentType.getPositionNearType(tagSet, idx)
+        if self.componentType:
+            return self.componentType.getPositionNearType(tagSet, idx)
         else:
             return idx
-    
+
+
 class Set(SequenceAndSetBase):
-    tagSet = baseTagSet = tag.initTagSet(
+    __doc__ = SequenceAndSetBase.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.initTagSet(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+    )
+
+    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+    #: object representing ASN.1 type allowed within |ASN.1| type
+    componentType = namedtype.NamedTypes()
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing constraints on |ASN.1| objects
+    sizeSpec = constraint.ConstraintsIntersection()
+
+    # Disambiguation ASN.1 types identification
+    typeId = SequenceAndSetBase.getTypeId()
+
+    def getComponent(self, innerFlag=False):
+        return self
+
+    def getComponentByType(self, tagSet, innerFlag=False):
+        """Returns |ASN.1| type component by ASN.1 tag.
+
+        Parameters
+        ----------
+        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tags to identify one of
+            |ASN.1| object component
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.base.PyAsn1Item`
+            a pyasn1 object
+        """
+        component = self.getComponentByPosition(
+            self.componentType.getPositionByType(tagSet)
         )
-    typeId = 4
-
-    def getComponent(self, innerFlag=0): return self
-    
-    def getComponentByType(self, tagSet, innerFlag=0):
-        c = self.getComponentByPosition(
-            self._componentType.getPositionByType(tagSet)
-            )
-        if innerFlag and isinstance(c, Set):
+        if innerFlag and isinstance(component, Set):
             # get inner component by inner tagSet
-            return c.getComponent(1)
+            return component.getComponent(innerFlag=True)
         else:
             # get outer component by inner tagSet
-            return c
-        
-    def setComponentByType(self, tagSet, value=None, innerFlag=0,
-                           verifyConstraints=True):
-        idx = self._componentType.getPositionByType(tagSet)
-        t = self._componentType.getTypeByPosition(idx)
+            return component
+
+    def setComponentByType(self, tagSet, value=noValue,
+                           verifyConstraints=True,
+                           matchTags=True,
+                           matchConstraints=True,
+                           innerFlag=False):
+        """Assign |ASN.1| type component by ASN.1 tag.
+
+        Parameters
+        ----------
+        tagSet : :py:class:`~pyasn1.type.tag.TagSet`
+            Object representing ASN.1 tags to identify one of
+            |ASN.1| object component
+
+        value : :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+            A Python value to initialize |ASN.1| component with (if *componentType* is set)
+            or ASN.1 value object to assign to |ASN.1| component.
+
+        verifyConstraints : :class:`bool`
+            If `False`, skip constraints validation
+
+        matchTags: :class:`bool`
+            If `False`, skip component tags matching
+
+        matchConstraints: :class:`bool`
+            If `False`, skip component constraints matching
+
+        innerFlag: :class:`bool`
+            If `True`, search for matching *tagSet* recursively.
+
+        Returns
+        -------
+        self
+        """
+        idx = self.componentType.getPositionByType(tagSet)
+
         if innerFlag:  # set inner component by inner tagSet
-            if t.getTagSet():
+            componentType = self.componentType.getTypeByPosition(idx)
+
+            if componentType.tagSet:
                 return self.setComponentByPosition(
-                    idx, value, verifyConstraints
-                    )
+                    idx, value, verifyConstraints, matchTags, matchConstraints
+                )
             else:
-                t = self.setComponentByPosition(idx).getComponentByPosition(idx)
-                return t.setComponentByType(
-                    tagSet, value, innerFlag, verifyConstraints
-                    )
+                componentType = self.getComponentByPosition(idx)
+                return componentType.setComponentByType(
+                    tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
+                )
         else:  # set outer component by inner tagSet
             return self.setComponentByPosition(
-                idx, value, verifyConstraints
-                )
-            
-    def getComponentTagMap(self):
-        if self._componentType:
-            return self._componentType.getTagMap(True)
-
-    def getComponentPositionByType(self, tagSet):
-        if self._componentType:
-            return self._componentType.getPositionByType(tagSet)
+                idx, value, verifyConstraints, matchTags, matchConstraints
+            )
+
+    @property
+    def componentTagMap(self):
+        if self.componentType:
+            return self.componentType.tagMapUnique
+
 
 class Choice(Set):
-    tagSet = baseTagSet = tag.TagSet()  # untagged
+    __doc__ = Set.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.TagSet()  # untagged
+
+    #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
+    #: object representing ASN.1 type allowed within |ASN.1| type
+    componentType = namedtype.NamedTypes()
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
+    #: object imposing size constraint on |ASN.1| objects
     sizeSpec = constraint.ConstraintsIntersection(
         constraint.ValueSizeConstraint(1, 1)
-        )
-    typeId = 5
+    )
+
+    # Disambiguation ASN.1 types identification
+    typeId = Set.getTypeId()
+
     _currentIdx = None
 
     def __eq__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] == other
         return NotImplemented
+
     def __ne__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] != other
         return NotImplemented
+
     def __lt__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] < other
         return NotImplemented
+
     def __le__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] <= other
         return NotImplemented
+
     def __gt__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] > other
         return NotImplemented
+
     def __ge__(self, other):
         if self._componentValues:
             return self._componentValues[self._currentIdx] >= other
         return NotImplemented
+
     if sys.version_info[0] <= 2:
-        def __nonzero__(self): return bool(self._componentValues)
+        def __nonzero__(self):
+            return self._componentValues and True or False
     else:
-        def __bool__(self): return bool(self._componentValues)
-
-    def __len__(self): return self._currentIdx is not None and 1 or 0
-    
+        def __bool__(self):
+            return self._componentValues and True or False
+
+    def __len__(self):
+        return self._currentIdx is not None and 1 or 0
+
+    def __contains__(self, key):
+        if self._currentIdx is None:
+            return False
+        return key == self.componentType[self._currentIdx].getName()
+
+    def __iter__(self):
+        if self._currentIdx is None:
+            raise StopIteration
+        yield self.componentType[self._currentIdx].getName()
+
+    # Python dict protocol
+
+    def values(self):
+        if self._currentIdx is not None:
+            yield self._componentValues[self._currentIdx]
+
+    def keys(self):
+        if self._currentIdx is not None:
+            yield self.componentType[self._currentIdx].getName()
+
+    def items(self):
+        if self._currentIdx is not None:
+            yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
+
     def verifySizeSpec(self):
         if self._currentIdx is None:
             raise error.PyAsn1Error('Component not chosen')
-        else:
-            self._sizeSpec(' ')
 
     def _cloneComponentValues(self, myClone, cloneValueFlag):
         try:
-            c = self.getComponent()
+            component = self.getComponent()
         except error.PyAsn1Error:
             pass
         else:
-            if isinstance(c, Choice):
-                tagSet = c.getEffectiveTagSet()
-            else:
-                tagSet = c.getTagSet()
-            if isinstance(c, base.AbstractConstructedAsn1Item):
-                myClone.setComponentByType(
-                    tagSet, c.clone(cloneValueFlag=cloneValueFlag)
-                    )
+            if isinstance(component, Choice):
+                tagSet = component.effectiveTagSet
             else:
-                myClone.setComponentByType(tagSet, c.clone())
-
-    def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
-        l = len(self._componentValues)
-        if idx >= l:
-            self._componentValues = self._componentValues + (idx-l+1)*[None]
-        if self._currentIdx is not None:
-            self._componentValues[self._currentIdx] = None
-        if value is None:
-            if self._componentValues[idx] is None:
-                self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
-                self._componentValuesSet = 1
-                self._currentIdx = idx
-            return self
-        elif not isinstance(value, base.Asn1Item):
-            value = self._componentType.getTypeByPosition(idx).clone(
-                value=value
+                tagSet = component.tagSet
+            if isinstance(component, base.AbstractConstructedAsn1Item):
+                myClone.setComponentByType(
+                    tagSet, component.clone(cloneValueFlag=cloneValueFlag)
                 )
-        if verifyConstraints:
-            if self._componentTypeLen:
-                self._verifyComponent(idx, value)
-            self._verifySubtypeSpec(value, idx)            
-        self._componentValues[idx] = value
+            else:
+                myClone.setComponentByType(tagSet, component.clone())
+
+    def getComponentByPosition(self, idx):
+        __doc__ = Set.__doc__
+
+        if self._currentIdx is None or self._currentIdx != idx:
+            return Set.getComponentByPosition(self, idx)
+
+        return self._componentValues[idx]
+
+    def setComponentByPosition(self, idx, value=noValue,
+                               verifyConstraints=True,
+                               matchTags=True,
+                               matchConstraints=True):
+        """Assign |ASN.1| type component by position.
+
+        Equivalent to Python sequence item assignment operation (e.g. `[]`).
+
+        Parameters
+        ----------
+        idx: :class:`int`
+            Component index (zero-based). Must either refer to existing
+            component or to N+1 component. In the latter case a new component
+            type gets instantiated (if *componentType* is set, or given ASN.1
+            object is taken otherwise) and appended to the |ASN.1| sequence.
+
+        value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
+            A Python value to initialize |ASN.1| component with (if *componentType* is set)
+            or ASN.1 value object to assign to |ASN.1| component. Once a new value is
+            set to *idx* component, previous value is dropped.
+
+        verifyConstraints : :class:`bool`
+            If `False`, skip constraints validation
+
+        matchTags: :class:`bool`
+            If `False`, skip component tags matching
+
+        matchConstraints: :class:`bool`
+            If `False`, skip component constraints matching
+
+        Returns
+        -------
+        self
+        """
+        oldIdx = self._currentIdx
+        Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
         self._currentIdx = idx
-        self._componentValuesSet = 1
+        if oldIdx is not None and oldIdx != idx:
+            self._componentValues[oldIdx] = None
         return self
 
-    def getMinTagSet(self):
-        if self._tagSet:
-            return self._tagSet
+    @property
+    def minTagSet(self):
+        if self.tagSet:
+            return self.tagSet
         else:
-            return self._componentType.genMinTagSet()
-
-    def getEffectiveTagSet(self):
-        if self._tagSet:
-            return self._tagSet
+            return self.componentType.minTagSet
+
+    @property
+    def effectiveTagSet(self):
+        """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
+        if self.tagSet:
+            return self.tagSet
         else:
-            c = self.getComponent()
-            if isinstance(c, Choice):
-                return c.getEffectiveTagSet()
-            else:
-                return c.getTagSet()
-
-    def getTagMap(self):
-        if self._tagSet:
-            return Set.getTagMap(self)
+            component = self.getComponent()
+            return component.effectiveTagSet
+
+    @property
+    def tagMap(self):
+        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
+            ASN.1 tags to ASN.1 objects contained within callee.
+        """
+        if self.tagSet:
+            return Set.tagMap.fget(self)
         else:
-            return Set.getComponentTagMap(self)
+            return self.componentType.tagMapUnique
 
     def getComponent(self, innerFlag=0):
+        """Return currently assigned component of the |ASN.1| object.
+
+        Returns
+        -------
+        : :py:class:`~pyasn1.type.base.PyAsn1Item`
+            a PyASN1 object
+        """
         if self._currentIdx is None:
             raise error.PyAsn1Error('Component not chosen')
         else:
             c = self._componentValues[self._currentIdx]
             if innerFlag and isinstance(c, Choice):
                 return c.getComponent(innerFlag)
             else:
                 return c
 
-    def getName(self, innerFlag=0):
+    def getName(self, innerFlag=False):
+        """Return the name of currently assigned component of the |ASN.1| object.
+
+        Returns
+        -------
+        : :py:class:`str`
+            |ASN.1| component name
+        """
         if self._currentIdx is None:
             raise error.PyAsn1Error('Component not chosen')
         else:
             if innerFlag:
                 c = self._componentValues[self._currentIdx]
                 if isinstance(c, Choice):
                     return c.getName(innerFlag)
-            return self._componentType.getNameByPosition(self._currentIdx)
-
-    def setDefaultComponents(self): pass
+            return self.componentType.getNameByPosition(self._currentIdx)
+
+    @property
+    def isValue(self):
+        """Indicate if |ASN.1| component is set and represents ASN.1 type or ASN.1 value.
+
+        The PyASN1 type objects can only participate in types comparison
+        and serve as a blueprint for serialization codecs to resolve
+        ambiguous types.
+
+        The PyASN1 value objects can additionally participate in most
+        of built-in Python operations.
+
+        Returns
+        -------
+        : :class:`bool`
+            :class:`True` if |ASN.1| component is set and represent value and type,
+            :class:`False` if |ASN.1| component is not set or it represents just ASN.1 type.
+        """
+        if self._currentIdx is None:
+            return False
+
+        return self._componentValues[self._currentIdx].isValue
+
+    # compatibility stubs
+
+    def getMinTagSet(self):
+        return self.minTagSet
+
 
 class Any(OctetString):
-    tagSet = baseTagSet = tag.TagSet()  # untagged
-    typeId = 6
-
-    def getTagMap(self):
-        return tagmap.TagMap(
-            { self.getTagSet(): self },
-            { eoo.endOfOctets.getTagSet(): eoo.endOfOctets },
-            self
+    __doc__ = OctetString.__doc__
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
+    #: associated with |ASN.1| type.
+    tagSet = tag.TagSet()  # untagged
+
+    #: Set (on class, not on instance) or return a
+    #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
+    #: imposing constraints on |ASN.1| type initialization values.
+    subtypeSpec = constraint.ConstraintsIntersection()
+
+    # Disambiguation ASN.1 types identification
+    typeId = OctetString.getTypeId()
+
+    @property
+    def tagMap(self):
+        """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
+            ASN.1 tags to ASN.1 objects contained within callee.
+        """
+        try:
+            return self._tagMap
+
+        except AttributeError:
+            self._tagMap = tagmap.TagMap(
+                {self.tagSet: self},
+                {eoo.endOfOctets.tagSet: eoo.endOfOctets},
+                self
             )
 
+            return self._tagMap
+
 # XXX
 # coercion rules?
--- a/third_party/python/pyasn1/pyasn1/type/useful.py
+++ b/third_party/python/pyasn1/pyasn1/type/useful.py
@@ -1,12 +1,187 @@
-# ASN.1 "useful" types
-from pyasn1.type import char, tag
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import datetime
+from pyasn1.type import univ, char, tag
+from pyasn1.compat import string, dateandtime
+from pyasn1 import error
+
+__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime']
+
+NoValue = univ.NoValue
+noValue = univ.noValue
+
+
+class ObjectDescriptor(char.GraphicString):
+    __doc__ = char.GraphicString.__doc__
+
+    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
+    tagSet = char.GraphicString.tagSet.tagImplicitly(
+        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7)
+    )
+
+    # Optimization for faster codec lookup
+    typeId = char.GraphicString.getTypeId()
+
+
+class TimeMixIn(object):
+
+    _yearsDigits = 4
+    _hasSubsecond = False
+    _optionalMinutes = False
+    _shortTZ = False
+
+    class FixedOffset(datetime.tzinfo):
+        """Fixed offset in minutes east from UTC."""
+
+        # defaulted arguments required
+        # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html
+        def __init__(self, offset=0, name='UTC'):
+            self.__offset = datetime.timedelta(minutes=offset)
+            self.__name = name
+
+        def utcoffset(self, dt):
+            return self.__offset
+
+        def tzname(self, dt):
+            return self.__name
+
+        def dst(self, dt):
+            return datetime.timedelta(0)
+
+    UTC = FixedOffset()
+
+    @property
+    def asDateTime(self):
+        """Create :py:class:`datetime.datetime` object from a |ASN.1| object.
+
+        Returns
+        -------
+        :
+            new instance of :py:class:`datetime.datetime` object            
+        """
+        text = str(self)
+        if text.endswith('Z'):
+            tzinfo = TimeMixIn.UTC
+            text = text[:-1]
+
+        elif '-' in text or '+' in text:
+            if '+' in text:
+                text, plusminus, tz = string.partition(text, '+')
+            else:
+                text, plusminus, tz = string.partition(text, '-')
+
+            if self._shortTZ and len(tz) == 2:
+                tz += '00'
 
-class GeneralizedTime(char.VisibleString):
+            if len(tz) != 4:
+                raise error.PyAsn1Error('malformed time zone offset %s' % tz)
+
+            try:
+                minutes = int(tz[:2]) * 60 + int(tz[2:])
+                if plusminus == '-':
+                    minutes *= -1
+
+            except ValueError:
+                raise error.PyAsn1Error('unknown time specification %s' % self)
+
+            tzinfo = TimeMixIn.FixedOffset(minutes, '?')
+
+        else:
+            tzinfo = None
+
+        if '.' in text or ',' in text:
+            if '.' in text:
+                text, _, ms = string.partition(text, '.')
+            else:
+                text, _, ms = string.partition(text, ',')
+
+            try:
+                ms = int(ms) * 10000
+
+            except ValueError:
+                raise error.PyAsn1Error('bad sub-second time specification %s' % self)
+
+        else:
+            ms = 0
+
+        if self._optionalMinutes and len(text) - self._yearsDigits == 6:
+            text += '0000'
+        elif len(text) - self._yearsDigits == 8:
+            text += '00'
+
+        try:
+            dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
+
+        except ValueError:
+            raise error.PyAsn1Error('malformed datetime format %s' % self)
+
+        return dt.replace(microsecond=ms, tzinfo=tzinfo)
+
+    @classmethod
+    def fromDateTime(cls, dt):
+        """Create |ASN.1| object from a :py:class:`datetime.datetime` object.
+
+        Parameters
+        ----------
+        dt : :py:class:`datetime.datetime` object
+            The `datetime.datetime` object to initialize the |ASN.1| object from
+            
+        
+        Returns
+        -------
+        :
+            new instance of |ASN.1| value
+        """
+        text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
+        if cls._hasSubsecond:
+            text += '.%d' % (dt.microsecond // 10000)
+
+        if dt.utcoffset():
+            seconds = dt.utcoffset().seconds
+            if seconds < 0:
+                text += '-'
+            else:
+                text += '+'
+            text += '%.2d%.2d' % (seconds // 3600, seconds % 3600)
+        else:
+            text += 'Z'
+
+        return cls(text)
+
+
+class GeneralizedTime(char.VisibleString, TimeMixIn):
+    __doc__ = char.VisibleString.__doc__
+
+    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
     tagSet = char.VisibleString.tagSet.tagImplicitly(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24)
-        )
+    )
+
+    # Optimization for faster codec lookup
+    typeId = char.VideotexString.getTypeId()
 
-class UTCTime(char.VisibleString):
+    _yearsDigits = 4
+    _hasSubsecond = True
+    _optionalMinutes = True
+    _shortTZ = True
+
+
+class UTCTime(char.VisibleString, TimeMixIn):
+    __doc__ = char.VisibleString.__doc__
+
+    #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
     tagSet = char.VisibleString.tagSet.tagImplicitly(
         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23)
-        )
+    )
+
+    # Optimization for faster codec lookup
+    typeId = char.VideotexString.getTypeId()
+
+    _yearsDigits = 2
+    _hasSubsecond = False
+    _optionalMinutes = False
+    _shortTZ = False
--- a/third_party/python/pyasn1/setup.cfg
+++ b/third_party/python/pyasn1/setup.cfg
@@ -1,5 +1,8 @@
+[bdist_wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0
 tag_svn_revision = 0
 
--- a/third_party/python/pyasn1/setup.py
+++ b/third_party/python/pyasn1/setup.py
@@ -1,115 +1,120 @@
 #!/usr/bin/env python
-"""ASN.1 types and codecs
-
-   A pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208).
-"""
-
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
 import os
 import sys
 
 classifiers = """\
 Development Status :: 5 - Production/Stable
 Environment :: Console
 Intended Audience :: Developers
 Intended Audience :: Education
 Intended Audience :: Information Technology
-Intended Audience :: Science/Research
 Intended Audience :: System Administrators
 Intended Audience :: Telecommunications Industry
 License :: OSI Approved :: BSD License
 Natural Language :: English
 Operating System :: OS Independent
 Programming Language :: Python :: 2
+Programming Language :: Python :: 2.4
+Programming Language :: Python :: 2.5
+Programming Language :: Python :: 2.6
+Programming Language :: Python :: 2.7
 Programming Language :: Python :: 3
+Programming Language :: Python :: 3.2
+Programming Language :: Python :: 3.3
+Programming Language :: Python :: 3.4
+Programming Language :: Python :: 3.5
+Programming Language :: Python :: 3.6
 Topic :: Communications
-Topic :: Security :: Cryptography
 Topic :: Software Development :: Libraries :: Python Modules
 """
 
-def howto_install_distribute():
-    print("""
-   Error: You need the distribute Python package!
-
-   It's very easy to install it, just type (as root on Linux):
-
-   wget http://python-distribute.org/distribute_setup.py
-   python distribute_setup.py
-
-   Then you could make eggs from this package.
-""")
 
 def howto_install_setuptools():
     print("""
    Error: You need setuptools Python package!
 
-   It's very easy to install it, just type (as root on Linux):
+   It's very easy to install it, just type:
 
-   wget http://peak.telecommunity.com/dist/ez_setup.py
+   wget https://bootstrap.pypa.io/ez_setup.py
    python ez_setup.py
 
    Then you could make eggs from this package.
 """)
 
+
+if sys.version_info[:2] < (2, 4):
+    print("ERROR: this package requires Python 2.4 or later!")
+    sys.exit(1)
+
 try:
     from setuptools import setup, Command
+
     params = {
         'zip_safe': True
-    }    
+    }
+
 except ImportError:
     for arg in sys.argv:
-        if arg.find('egg') != -1:
-            if sys.version_info[0] > 2:
-                howto_install_distribute()
-            else:
-                howto_install_setuptools()
+        if 'egg' in arg:
+            howto_install_setuptools()
             sys.exit(1)
     from distutils.core import setup, Command
+
     params = {}
 
-doclines = [ x.strip() for x in __doc__.split('\n') if x ]
-
-params.update( {
+params.update({
     'name': 'pyasn1',
-    'version': open(os.path.join('pyasn1','__init__.py')).read().split('\'')[1],
-    'description': doclines[0],
-    'long_description': ' '.join(doclines[1:]),
-    'maintainer': 'Ilya Etingof <ilya@glas.net>',
+    'version': open(os.path.join('pyasn1', '__init__.py')).read().split('\'')[1],
+    'description': 'ASN.1 types and codecs',
+    'long_description': 'Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)',
+    'maintainer': 'Ilya Etingof <etingof@gmail.com>',
     'author': 'Ilya Etingof',
-    'author_email': 'ilya@glas.net',
-    'url': 'http://sourceforge.net/projects/pyasn1/',
+    'author_email': 'etingof@gmail.com',
+    'url': 'https://github.com/etingof/pyasn1',
     'platforms': ['any'],
-    'classifiers': [ x for x in classifiers.split('\n') if x ],
+    'classifiers': [x for x in classifiers.split('\n') if x],
     'license': 'BSD',
-    'packages': [ 'pyasn1',
-                  'pyasn1.type',
-                  'pyasn1.compat',
-                  'pyasn1.codec',
-                  'pyasn1.codec.ber',
-                  'pyasn1.codec.cer',
-                  'pyasn1.codec.der' ]
-} )
+    'packages': ['pyasn1',
+                 'pyasn1.type',
+                 'pyasn1.compat',
+                 'pyasn1.codec',
+                 'pyasn1.codec.ber',
+                 'pyasn1.codec.cer',
+                 'pyasn1.codec.der',
+                 'pyasn1.codec.native']})
 
 # handle unittest discovery feature
-if sys.version_info[0:2] < (2, 7) or \
-   sys.version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        unittest = None
-else:
+try:
+    import unittest2 as unittest
+except ImportError:
     import unittest
 
-if unittest:
-    class PyTest(Command):
-        user_options = []
+
+class PyTest(Command):
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
 
-        def initialize_options(self): pass
-        def finalize_options(self): pass
+    def run(self):
+        suite = unittest.TestLoader().loadTestsFromNames(
+            ['tests.__main__.suite']
+        )
 
-        def run(self):
-            suite = unittest.defaultTestLoader.discover('.')
-            unittest.TextTestRunner(verbosity=2).run(suite)
+        unittest.TextTestRunner(verbosity=2).run(suite)
 
-    params['cmdclass'] = { 'test': PyTest }
+params['cmdclass'] = {
+    'test': PyTest,
+    'tests': PyTest,
+}
 
 setup(**params)
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'ber')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
-    suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/test_decoder.py
+++ /dev/null
@@ -1,535 +0,0 @@
-from pyasn1.type import tag, namedtype, univ
-from pyasn1.codec.ber import decoder
-from pyasn1.compat.octets import ints2octs, str2octs, null
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class LargeTagDecoderTestCase(unittest.TestCase):
-    def testLargeTag(self):
-        assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null)
-
-class IntegerDecoderTestCase(unittest.TestCase):
-    def testPosInt(self):
-        assert decoder.decode(ints2octs((2, 1, 12))) == (12, null)
-    def testNegInt(self):
-        assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null)
-    def testZero(self):
-        assert decoder.decode(ints2octs((2, 0))) == (0, null)
-    def testZeroLong(self):
-        assert decoder.decode(ints2octs((2, 1, 0))) == (0, null)
-    def testMinusOne(self):
-        assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null)
-    def testPosLong(self):
-        assert decoder.decode(
-            ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
-            ) == (0xffffffffffffffff, null)
-    def testNegLong(self):
-        assert decoder.decode(
-            ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
-            ) == (-0xffffffffffffffff, null)
-    def testSpec(self):
-        try:
-            decoder.decode(
-                ints2octs((2, 1, 12)), asn1Spec=univ.Null()
-                ) == (12, null)
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong asn1Spec worked out'
-        assert decoder.decode(
-            ints2octs((2, 1, 12)), asn1Spec=univ.Integer()
-            ) == (12, null)
-    def testTagFormat(self):
-        try:
-            decoder.decode(ints2octs((34, 1, 12)))
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class BooleanDecoderTestCase(unittest.TestCase):
-    def testTrue(self):
-        assert decoder.decode(ints2octs((1, 1, 1))) == (1, null)
-    def testTrueNeg(self):
-        assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
-    def testExtraTrue(self):
-        assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50)))
-    def testFalse(self):
-        assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
-    def testTagFormat(self):
-        try:
-            decoder.decode(ints2octs((33, 1, 1)))
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class BitStringDecoderTestCase(unittest.TestCase):
-    def testDefMode(self):
-        assert decoder.decode(
-            ints2octs((3, 3, 1, 169, 138))
-            ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
-    def testIndefMode(self):
-        assert decoder.decode(
-            ints2octs((3, 3, 1, 169, 138))
-            ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
-    def testDefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
-            ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
-    def testIndefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
-            ) == ((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1), null)
-    def testDefModeChunkedSubst(self):
-        assert decoder.decode(
-            ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), 8)
-    def testIndefModeChunkedSubst(self):
-        assert decoder.decode(
-            ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), -1)
-        
-class OctetStringDecoderTestCase(unittest.TestCase):
-    def testDefMode(self):
-        assert decoder.decode(
-            ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-            ) == (str2octs('Quick brown fox'), null)
-    def testIndefMode(self):
-        assert decoder.decode(
-            ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
-            ) == (str2octs('Quick brown fox'), null)
-    def testDefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
-            ) == (str2octs('Quick brown fox'), null)
-    def testIndefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0))
-            ) == (str2octs('Quick brown fox'), null)
-    def testDefModeChunkedSubst(self):
-        assert decoder.decode(
-            ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), 23)
-    def testIndefModeChunkedSubst(self):
-        assert decoder.decode(
-            ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), -1)
-        
-class ExpTaggedOctetStringDecoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.o = univ.OctetString(
-            'Quick brown fox',
-            tagSet=univ.OctetString.tagSet.tagExplicitly(
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
-            ))
-
-    def testDefMode(self):
-        assert self.o.isSameTypeWith(decoder.decode(
-            ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-            )[0])
-
-    def testIndefMode(self):
-        v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)))
-        assert self.o.isSameTypeWith(v)
-        assert not s
-
-    def testDefModeChunked(self):
-        v, s = decoder.decode(ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)))
-        assert self.o.isSameTypeWith(v)
-        assert not s
-
-    def testIndefModeChunked(self):
-        v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0)))
-        assert self.o.isSameTypeWith(v)
-        assert not s
-
-    def testDefModeSubst(self):
-        assert decoder.decode(
-            ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), 17)
-
-    def testIndefModeSubst(self):
-        assert decoder.decode(
-            ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), -1)
-  
-class NullDecoderTestCase(unittest.TestCase):
-    def testNull(self):
-        assert decoder.decode(ints2octs((5, 0))) == (null, null)
-    def testTagFormat(self):
-        try:
-            decoder.decode(ints2octs((37, 0)))
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class ObjectIdentifierDecoderTestCase(unittest.TestCase):
-    def testOID(self):
-        assert decoder.decode(
-            ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
-            ) == ((1,3,6,0,0xffffe), null)
-
-    def testEdges1(self):
-        assert decoder.decode(
-            ints2octs((6, 1, 255))
-            ) == ((6,15), null)
-
-    def testEdges2(self):
-        assert decoder.decode(
-            ints2octs((6, 1, 239))
-            ) == ((5,39), null)
-
-    def testEdges3(self):
-        assert decoder.decode(
-            ints2octs((6, 7, 43, 6, 143, 255, 255, 255, 127))
-            ) == ((1, 3, 6, 4294967295), null)
-
-    def testNonLeading0x80(self):
-        assert decoder.decode(
-            ints2octs((6, 5, 85, 4, 129, 128, 0)),
-            ) == ((2, 5, 4, 16384), null)
-
-    def testLeading0x80(self):
-        try:
-            decoder.decode(
-                ints2octs((6, 5, 85, 4, 128, 129, 0))
-            )
-        except PyAsn1Error:
-            pass
-        else:
-            assert 1, 'Leading 0x80 tolarated'
-
-    def testTagFormat(self):
-        try:
-            decoder.decode(ints2octs((38, 1, 239)))
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class RealDecoderTestCase(unittest.TestCase):
-    def testChar(self):
-        assert decoder.decode(
-            ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
-        ) == (univ.Real((123, 10, 11)), null)
-
-    def testBin1(self):
-        assert decoder.decode(
-            ints2octs((9, 4, 128, 245, 4, 77))
-        ) == (univ.Real((1101, 2, -11)), null)
-
-    def testBin2(self):
-        assert decoder.decode(
-            ints2octs((9, 4, 128, 11, 4, 77))
-        ) == (univ.Real((1101, 2, 11)), null)
-
-    def testBin3(self):
-        assert decoder.decode(
-            ints2octs((9, 3, 192, 10, 123))
-        ) == (univ.Real((-123, 2, 10)), null)
-
-
-    def testPlusInf(self):
-        assert decoder.decode(
-            ints2octs((9, 1, 64))
-        ) == (univ.Real('inf'), null)
- 
-    def testMinusInf(self):
-        assert decoder.decode(
-            ints2octs((9, 1, 65))
-        ) == (univ.Real('-inf'), null)
-
-    def testEmpty(self):
-        assert decoder.decode(
-            ints2octs((9, 0))
-        ) == (univ.Real(0.0), null)
- 
-    def testTagFormat(self):
-        try:
-            decoder.decode(ints2octs((41, 0)))
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class SequenceDecoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Sequence(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null(null)),
-            namedtype.NamedType('first-name', univ.OctetString(null)),
-            namedtype.NamedType('age', univ.Integer(33)),
-            ))
-        self.s.setComponentByPosition(0, univ.Null(null))
-        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
-        self.s.setComponentByPosition(2, univ.Integer(1))
-        self.s.setDefaultComponents()
-        
-    def testWithOptionalAndDefaultedDefMode(self):
-        assert decoder.decode(
-            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
-            ) == (self.s, null)
-        
-    def testWithOptionalAndDefaultedIndefMode(self):
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedDefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedIndefModeChunked(self):
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedDefModeSubst(self):
-        assert decoder.decode(
-            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), 18)
-        
-    def testWithOptionalAndDefaultedIndefModeSubst(self):
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), -1)
-
-    def testTagFormat(self):
-        try:
-            decoder.decode(
-                ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
-            )
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'wrong tagFormat worked out'
-
-class GuidedSequenceDecoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Sequence(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null(null)),
-            namedtype.OptionalNamedType('first-name', univ.OctetString(null)),
-            namedtype.DefaultedNamedType('age', univ.Integer(33)),
-            ))
-
-    def __init(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(null))
-        self.s.setDefaultComponents()
-        
-    def __initWithOptional(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(null))
-        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
-        self.s.setDefaultComponents()
-
-    def __initWithDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(null))
-        self.s.setComponentByPosition(2, univ.Integer(1))
-        self.s.setDefaultComponents()
-        
-    def __initWithOptionalAndDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(null))
-        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
-        self.s.setComponentByPosition(2, univ.Integer(1))
-        self.s.setDefaultComponents()
-        
-    def testDefMode(self):
-        self.__init()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-        
-    def testIndefMode(self):
-        self.__init()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testDefModeChunked(self):
-        self.__init()
-        assert decoder.decode(
-            ints2octs((48, 2, 5, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testIndefModeChunked(self):
-        self.__init()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalDefMode(self):
-        self.__initWithOptional()
-        assert decoder.decode(
-            ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
-            ) == (self.s, null)
-        
-    def testWithOptionaIndefMode(self):
-        self.__initWithOptional()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)),
-            asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalDefModeChunked(self):
-        self.__initWithOptional()
-        assert decoder.decode(
-            ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)),
-            asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalIndefModeChunked(self):
-        self.__initWithOptional()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)),
-            asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithDefaultedDefMode(self):
-        self.__initWithDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
-            ) == (self.s, null)
-        
-    def testWithDefaultedIndefMode(self):
-        self.__initWithDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithDefaultedDefModeChunked(self):
-        self.__initWithDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithDefaultedIndefModeChunked(self):
-        self.__initWithDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedDefMode(self):
-        self.__initWithOptionalAndDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
-            ) == (self.s, null)
-        
-    def testWithOptionalAndDefaultedIndefMode(self):
-        self.__initWithOptionalAndDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedDefModeChunked(self):
-        self.__initWithOptionalAndDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithOptionalAndDefaultedIndefModeChunked(self):
-        self.__initWithOptionalAndDefaulted()
-        assert decoder.decode(
-            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-class ChoiceDecoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null(null)),
-            namedtype.NamedType('number', univ.Integer(0)),
-            namedtype.NamedType('string', univ.OctetString())
-            ))
-
-    def testBySpec(self):
-        self.s.setComponentByPosition(0, univ.Null(null))
-        assert decoder.decode(
-            ints2octs((5, 0)), asn1Spec=self.s
-            ) == (self.s, null)
-
-    def testWithoutSpec(self):
-        self.s.setComponentByPosition(0, univ.Null(null))
-        assert decoder.decode(ints2octs((5, 0))) == (self.s, null)
-        assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null)
-
-    def testUndefLength(self):
-        self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
-        assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)), asn1Spec=self.s) == (self.s, null)
-
-    def testExplicitTag(self):
-        s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
-                           tag.tagFormatConstructed, 4))
-        s.setComponentByPosition(0, univ.Null(null))
-        assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null)
-
-    def testExplicitTagUndefLength(self):
-        s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
-                           tag.tagFormatConstructed, 4))
-        s.setComponentByPosition(0, univ.Null(null))
-        assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null)
-
-class AnyDecoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Any()
-
-    def testByUntagged(self):
-        assert decoder.decode(
-            ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
-            ) == (univ.Any('\004\003fox'), null)
-
-    def testTaggedEx(self):
-        s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
-        assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
-                
-    def testTaggedIm(self):
-        s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
-        assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
-
-    def testByUntaggedIndefMode(self):
-        assert decoder.decode(
-            ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
-            ) == (univ.Any('\004\003fox'), null)
-
-    def testTaggedExIndefMode(self):
-        s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
-        assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
-                
-    def testTaggedImIndefMode(self):
-        s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
-        assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
-
-    def testByUntaggedSubst(self):
-        assert decoder.decode(
-            ints2octs((4, 3, 102, 111, 120)),
-            asn1Spec=self.s,
-            substrateFun=lambda a,b,c: (b,c)
-            ) == (ints2octs((4, 3, 102, 111, 120)), 5)
-
-    def testTaggedExSubst(self):
-        assert decoder.decode(
-            ints2octs((164, 5, 4, 3, 102, 111, 120)),
-            asn1Spec=self.s,
-            substrateFun=lambda a,b,c: (b,c)
-        ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), 7)
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/ber/test_encoder.py
+++ /dev/null
@@ -1,338 +0,0 @@
-from pyasn1.type import tag, namedtype, univ
-from pyasn1.codec.ber import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class LargeTagEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.o = univ.Integer().subtype(
-            value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf)
-            )
-    def testEncoder(self):
-        assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))
-        
-class IntegerEncoderTestCase(unittest.TestCase):
-    def testPosInt(self):
-        assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12))
-        
-    def testNegInt(self):
-        assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244))
-        
-    def testZero(self):
-        assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0))
-
-    def testCompactZero(self):
-        encoder.IntegerEncoder.supportCompactZero = True
-        substrate = encoder.encode(univ.Integer(0))
-        encoder.IntegerEncoder.supportCompactZero = False
-        assert substrate == ints2octs((2, 0))
-        
-    def testMinusOne(self):
-        assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255))
-        
-    def testPosLong(self):
-        assert encoder.encode(
-            univ.Integer(0xffffffffffffffff)
-            ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
-        
-    def testNegLong(self):
-        assert encoder.encode(
-            univ.Integer(-0xffffffffffffffff)
-            ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
-
-class BooleanEncoderTestCase(unittest.TestCase):
-    def testTrue(self):
-        assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1))
-        
-    def testFalse(self):
-        assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
-
-class BitStringEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.b = univ.BitString((1,0,1,0,1,0,0,1,1,0,0,0,1,0,1))
-        
-    def testDefMode(self):
-        assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138))
-        
-    def testIndefMode(self):
-        assert encoder.encode(
-            self.b, defMode=0
-            ) == ints2octs((3, 3, 1, 169, 138))
-        
-    def testDefModeChunked(self):
-        assert encoder.encode(
-            self.b, maxChunkSize=1
-            ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
-        
-    def testIndefModeChunked(self):
-        assert encoder.encode(
-            self.b, defMode=0, maxChunkSize=1
-            ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
-        
-    def testEmptyValue(self):
-        assert encoder.encode(univ.BitString(())) == ints2octs((3, 1, 0))
-        
-class OctetStringEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.o = univ.OctetString('Quick brown fox')
-        
-    def testDefMode(self):
-        assert encoder.encode(self.o) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-        
-    def testIndefMode(self):
-        assert encoder.encode(
-            self.o, defMode=0
-            ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
-    def testDefModeChunked(self):
-        assert encoder.encode(
-            self.o, maxChunkSize=4
-            ) == ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
-
-    def testIndefModeChunked(self):
-        assert encoder.encode(
-            self.o, defMode=0, maxChunkSize=4
-            ) == ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0))
-        
-class ExpTaggedOctetStringEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.o = univ.OctetString().subtype(
-            value='Quick brown fox',
-            explicitTag=tag.Tag(tag.tagClassApplication,tag.tagFormatSimple,5)
-            )
-    def testDefMode(self):
-        assert encoder.encode(self.o) == ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
-    def testIndefMode(self):
-        assert encoder.encode(
-            self.o, defMode=0
-            ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
-        
-    def testDefModeChunked(self):
-        assert encoder.encode(
-            self.o, defMode=1, maxChunkSize=4
-            ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
-        
-    def testIndefModeChunked(self):
-        assert encoder.encode(
-            self.o, defMode=0, maxChunkSize=4
-            ) == ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
-
-class NullEncoderTestCase(unittest.TestCase):
-    def testNull(self):
-        assert encoder.encode(univ.Null('')) == ints2octs((5, 0))
-
-class ObjectIdentifierEncoderTestCase(unittest.TestCase):
-    def testNull(self):
-        assert encoder.encode(
-            univ.ObjectIdentifier((1,3,6,0,0xffffe))
-            ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
-
-class RealEncoderTestCase(unittest.TestCase):
-    def testChar(self):
-        assert encoder.encode(
-            univ.Real((123, 10, 11))
-            ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
-
-    def testBin1(self):
-        assert encoder.encode(
-            univ.Real((1101, 2, 11))
-            ) == ints2octs((9, 4, 128, 11, 4, 77))
-
-    def testBin2(self):
-        assert encoder.encode(
-            univ.Real((1101, 2, -11))
-            ) == ints2octs((9, 4, 128, 245, 4, 77))
-
-    def testPlusInf(self):
-        assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64))
-
-    def testMinusInf(self):
-        assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65))
-        
-    def testZero(self):
-        assert encoder.encode(univ.Real(0)) == ints2octs((9, 0))
-        
-class SequenceEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Sequence(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null('')),
-            namedtype.OptionalNamedType('first-name', univ.OctetString('')),
-            namedtype.DefaultedNamedType('age', univ.Integer(33)),
-            ))
-
-    def __init(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-        
-    def __initWithOptional(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByPosition(1, 'quick brown')
-        
-    def __initWithDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByPosition(2, 1)
-        
-    def __initWithOptionalAndDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(''))
-        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
-        self.s.setComponentByPosition(2, univ.Integer(1))
-        
-    def testDefMode(self):
-        self.__init()
-        assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0))
-        
-    def testIndefMode(self):
-        self.__init()
-        assert encoder.encode(
-            self.s, defMode=0
-            ) == ints2octs((48, 128, 5, 0, 0, 0))
-
-    def testDefModeChunked(self):
-        self.__init()
-        assert encoder.encode(
-            self.s, defMode=1, maxChunkSize=4
-            ) == ints2octs((48, 2, 5, 0))
-
-    def testIndefModeChunked(self):
-        self.__init()
-        assert encoder.encode(
-            self.s, defMode=0, maxChunkSize=4
-            ) == ints2octs((48, 128, 5, 0, 0, 0))
-
-    def testWithOptionalDefMode(self):
-        self.__initWithOptional()
-        assert encoder.encode(self.s) == ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
-        
-    def testWithOptionalIndefMode(self):
-        self.__initWithOptional()
-        assert encoder.encode(
-            self.s, defMode=0
-            ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
-
-    def testWithOptionalDefModeChunked(self):
-        self.__initWithOptional()
-        assert encoder.encode(
-            self.s, defMode=1, maxChunkSize=4
-            ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
-
-    def testWithOptionalIndefModeChunked(self):
-        self.__initWithOptional()
-        assert encoder.encode(
-            self.s, defMode=0, maxChunkSize=4
-            ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
-
-    def testWithDefaultedDefMode(self):
-        self.__initWithDefaulted()
-        assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1))
-        
-    def testWithDefaultedIndefMode(self):
-        self.__initWithDefaulted()
-        assert encoder.encode(
-            self.s, defMode=0
-            ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
-
-    def testWithDefaultedDefModeChunked(self):
-        self.__initWithDefaulted()
-        assert encoder.encode(
-            self.s, defMode=1, maxChunkSize=4
-            ) == ints2octs((48, 5, 5, 0, 2, 1, 1))
-
-    def testWithDefaultedIndefModeChunked(self):
-        self.__initWithDefaulted()
-        assert encoder.encode(
-            self.s, defMode=0, maxChunkSize=4
-            ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
-
-    def testWithOptionalAndDefaultedDefMode(self):
-        self.__initWithOptionalAndDefaulted()
-        assert encoder.encode(self.s) == ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
-        
-    def testWithOptionalAndDefaultedIndefMode(self):
-        self.__initWithOptionalAndDefaulted()
-        assert encoder.encode(
-            self.s, defMode=0
-            ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
-
-    def testWithOptionalAndDefaultedDefModeChunked(self):
-        self.__initWithOptionalAndDefaulted()
-        assert encoder.encode(
-            self.s, defMode=1, maxChunkSize=4
-            ) == ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
-
-    def testWithOptionalAndDefaultedIndefModeChunked(self):
-        self.__initWithOptionalAndDefaulted()
-        assert encoder.encode(
-            self.s, defMode=0, maxChunkSize=4
-            ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
-
-class ChoiceEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null('')),
-            namedtype.NamedType('number', univ.Integer(0)),
-            namedtype.NamedType('string', univ.OctetString())
-            ))
-
-    def testEmpty(self):
-        try:
-            encoder.encode(self.s)
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'encoded unset choice'
-        
-    def testFilled(self):
-        self.s.setComponentByPosition(0, univ.Null(''))
-        assert encoder.encode(self.s) == ints2octs((5, 0))
-
-    def testTagged(self):
-        s = self.s.subtype(
-            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,4)
-        )
-        s.setComponentByPosition(0, univ.Null(''))
-        assert encoder.encode(s) == ints2octs((164, 2, 5, 0))
-
-    def testUndefLength(self):
-        self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
-        assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0))
-
-    def testTaggedUndefLength(self):
-        s = self.s.subtype(
-            explicitTag=tag.Tag(tag.tagClassContext,tag.tagFormatConstructed,4)
-        )
-        s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
-        assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs((164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0))
-
-class AnyEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
-        
-    def testUntagged(self):
-        assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120))
-            
-    def testTaggedEx(self):
-        s = self.s.subtype(
-            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
-            )
-        assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120))
-
-    def testTaggedIm(self):
-        s = self.s.subtype(
-            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
-            )
-        assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120))
-                    
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'cer')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
-    suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/test_decoder.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from pyasn1.type import univ
-from pyasn1.codec.cer import decoder
-from pyasn1.compat.octets import ints2octs, str2octs, null
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class BooleanDecoderTestCase(unittest.TestCase):
-    def testTrue(self):
-        assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
-    def testFalse(self):
-        assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
-        
-class OctetStringDecoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert decoder.decode(
-            ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
-            ) == (str2octs('Quick brown fox'), null)
-    def testLongMode(self):
-        assert decoder.decode(
-            ints2octs((36, 128, 4, 130, 3, 232) + (81,)*1000 + (4, 1, 81, 0, 0))
-            ) == (str2octs('Q'*1001), null)
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/cer/test_encoder.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.codec.cer import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class BooleanEncoderTestCase(unittest.TestCase):
-    def testTrue(self):
-        assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255))
-    def testFalse(self):
-        assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
-
-class BitStringEncoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert encoder.encode(
-            univ.BitString((1,0)*501)
-            ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
-
-    def testLongMode(self):
-        assert encoder.encode(
-            univ.BitString((1,0)*501)
-            ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
-        
-class OctetStringEncoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert encoder.encode(
-            univ.OctetString('Quick brown fox')
-            ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-    def testLongMode(self):
-        assert encoder.encode(
-            univ.OctetString('Q'*1001)
-            ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,)*1000 + (4, 1, 81, 0, 0))
-        
-class SetEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        self.s = univ.Set(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null('')),
-            namedtype.OptionalNamedType('first-name', univ.OctetString('')),
-            namedtype.DefaultedNamedType('age', univ.Integer(33))
-            ))
-
-    def __init(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-    def __initWithOptional(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByPosition(1, 'quick brown')
-        
-    def __initWithDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByPosition(2, 1)
-        
-    def __initWithOptionalAndDefaulted(self):
-        self.s.clear()
-        self.s.setComponentByPosition(0, univ.Null(''))
-        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
-        self.s.setComponentByPosition(2, univ.Integer(1))
-        
-    def testIndefMode(self):
-        self.__init()
-        assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0))
-
-    def testWithOptionalIndefMode(self):
-        self.__initWithOptional()
-        assert encoder.encode(
-            self.s
-            ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
-
-    def testWithDefaultedIndefMode(self):
-        self.__initWithDefaulted()
-        assert encoder.encode(
-            self.s
-            ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0))
-
-    def testWithOptionalAndDefaultedIndefMode(self):
-        self.__initWithOptionalAndDefaulted()
-        assert encoder.encode(
-            self.s
-            ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
-
-class SetWithChoiceEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        c = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('actual', univ.Boolean(0))
-            ))
-        self.s = univ.Set(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null('')),
-            namedtype.NamedType('status', c)
-            ))
-
-    def testIndefMode(self):
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByName('status')
-        self.s.getComponentByName('status').setComponentByPosition(0, 1)
-        assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0))
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/suite.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'der')
-import test_encoder, test_decoder
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_encoder, test_decoder):
-    suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/test_decoder.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from pyasn1.type import univ
-from pyasn1.codec.der import decoder
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class OctetStringDecoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert decoder.decode(
-            '\004\017Quick brown fox'.encode()
-            ) == ('Quick brown fox'.encode(), ''.encode())
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/der/test_encoder.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.codec.der import encoder
-from pyasn1.compat.octets import ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class OctetStringEncoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert encoder.encode(
-            univ.OctetString('Quick brown fox')
-            ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
-
-class BitStringEncoderTestCase(unittest.TestCase):
-    def testShortMode(self):
-        assert encoder.encode(
-            univ.BitString((1,))
-            ) == ints2octs((3, 2, 7, 128))
-        
-class SetWithChoiceEncoderTestCase(unittest.TestCase):
-    def setUp(self):
-        c = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('name', univ.OctetString('')),
-            namedtype.NamedType('amount', univ.Integer(0))
-            ))
-        self.s = univ.Set(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('place-holder', univ.Null('')),
-            namedtype.NamedType('status', c)
-            ))
-
-    def testDefMode(self):
-        self.s.setComponentByPosition(0)
-        self.s.setComponentByName('status')
-        self.s.getComponentByName('status').setComponentByPosition(0, 'ann')
-        assert encoder.encode(self.s) == ints2octs((49, 7, 4, 3, 97, 110, 110, 5, 0))
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/codec/suite.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'codec'+sep+'ber')
-import ber.suite
-path.insert(1, path[0]+sep+'codec'+sep+'cer')
-import cer.suite
-path.insert(1, path[0]+sep+'codec'+sep+'der')
-import der.suite
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-for m in (
-    ber.suite,
-    cer.suite,
-    der.suite
-    ):
-    suite.addTest(getattr(m, 'suite'))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/suite.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from sys import path, version_info
-from os.path import sep
-path.insert(1, path[0]+sep+'type')
-import type.suite
-path.insert(1, path[0]+sep+'codec')
-import codec.suite
-from pyasn1.error import PyAsn1Error
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-for m in (
-    type.suite,
-    codec.suite
-    ):
-    suite.addTest(getattr(m, 'suite'))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-# This file is necessary to make this directory a package.
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/suite.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import test_tag, test_constraint, test_namedtype, test_univ
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
-for m in (test_tag, test_constraint, test_namedtype, test_univ):
-    suite.addTest(loader.loadTestsFromModule(m))
-
-def runTests(): unittest.TextTestRunner(verbosity=2).run(suite)
-
-if __name__ == '__main__': runTests()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_constraint.py
+++ /dev/null
@@ -1,280 +0,0 @@
-from pyasn1.type import constraint, error
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class SingleValueConstraintTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.SingleValueConstraint(1,2)
-        self.c2 = constraint.SingleValueConstraint(3,4)
-
-    def testCmp(self): assert self.c1 == self.c1, 'comparation fails'
-    def testHash(self): assert hash(self.c1) != hash(self.c2), 'hash() fails'
-    def testGoodVal(self):
-        try:
-            self.c1(1)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(4)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ContainedSubtypeConstraintTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ContainedSubtypeConstraint(
-            constraint.SingleValueConstraint(12)
-            )
-
-    def testGoodVal(self):
-        try:
-            self.c1(12)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(4)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ValueRangeConstraintTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ValueRangeConstraint(1,4)
-
-    def testGoodVal(self):
-        try:
-            self.c1(1)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(-5)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ValueSizeConstraintTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ValueSizeConstraint(1,2)
-
-    def testGoodVal(self):
-        try:
-            self.c1('a')
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1('abc')
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class PermittedAlphabetConstraintTestCase(SingleValueConstraintTestCase):
-    def setUp(self):
-        self.c1 = constraint.PermittedAlphabetConstraint('A', 'B', 'C')
-        self.c2 = constraint.PermittedAlphabetConstraint('DEF')
-
-    def testGoodVal(self):
-        try:
-            self.c1('A')
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1('E')
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ConstraintsIntersectionTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ConstraintsIntersection(
-            constraint.SingleValueConstraint(4),
-            constraint.ValueRangeConstraint(2, 4)
-            )
-
-    def testCmp1(self):
-        assert constraint.SingleValueConstraint(4) in self.c1, '__cmp__() fails'
-
-    def testCmp2(self):
-        assert constraint.SingleValueConstraint(5) not in self.c1, \
-               '__cmp__() fails'
-
-    def testCmp3(self):
-        c = constraint.ConstraintsUnion(constraint.ConstraintsIntersection(
-            constraint.SingleValueConstraint(4),
-            constraint.ValueRangeConstraint(2, 4)
-            ))
-        assert self.c1 in c, '__cmp__() fails'
-    def testCmp4(self):
-        c = constraint.ConstraintsUnion(
-            constraint.ConstraintsIntersection(constraint.SingleValueConstraint(5))
-            )
-        assert self.c1 not in c, '__cmp__() fails'
-        
-    def testGoodVal(self):
-        try:
-            self.c1(4)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(-5)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class InnerTypeConstraintTestCase(unittest.TestCase):
-    def testConst1(self):
-        c = constraint.InnerTypeConstraint(
-            constraint.SingleValueConstraint(4)
-            )
-        try:
-            c(4, 32)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-        try:
-            c(5, 32)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-    def testConst2(self):
-        c = constraint.InnerTypeConstraint(
-            (0, constraint.SingleValueConstraint(4), 'PRESENT'),
-            (1, constraint.SingleValueConstraint(4), 'ABSENT')
-            )
-        try:
-            c(4, 0)
-        except error.ValueConstraintError:
-            raise
-            assert 0, 'constraint check fails'            
-        try:
-            c(4, 1)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'            
-        try:
-            c(3, 0)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'            
-
-# Constraints compositions
-
-class ConstraintsIntersectionTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ConstraintsIntersection(
-            constraint.ValueRangeConstraint(1, 9),
-            constraint.ValueRangeConstraint(2, 5)
-            )
-
-    def testGoodVal(self):
-        try:
-            self.c1(3)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(0)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ConstraintsUnionTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ConstraintsUnion(
-            constraint.SingleValueConstraint(5),
-            constraint.ValueRangeConstraint(1, 3)
-            )
-
-    def testGoodVal(self):
-        try:
-            self.c1(2)
-            self.c1(5)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(-5)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-class ConstraintsExclusionTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ConstraintsExclusion(
-            constraint.ValueRangeConstraint(2, 4)
-            )
-
-    def testGoodVal(self):
-        try:
-            self.c1(6)
-        except error.ValueConstraintError:
-            assert 0, 'constraint check fails'
-    def testBadVal(self):
-        try:
-            self.c1(2)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint check fails'
-
-# Constraints derivations
-
-class DirectDerivationTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.SingleValueConstraint(5)
-        self.c2 = constraint.ConstraintsUnion(
-            self.c1, constraint.ValueRangeConstraint(1, 3)
-            )
-
-    def testGoodVal(self):
-        assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
-        assert not self.c1.isSubTypeOf(self.c2) , 'isSubTypeOf failed'
-    def testBadVal(self):
-        assert not self.c2.isSuperTypeOf(self.c1) , 'isSuperTypeOf failed'
-        assert self.c2.isSubTypeOf(self.c1) , 'isSubTypeOf failed'
-
-class IndirectDerivationTestCase(unittest.TestCase):
-    def setUp(self):
-        self.c1 = constraint.ConstraintsIntersection(
-            constraint.ValueRangeConstraint(1, 30)
-            )
-        self.c2 = constraint.ConstraintsIntersection(
-            self.c1, constraint.ValueRangeConstraint(1, 20)
-            )
-        self.c2 = constraint.ConstraintsIntersection(
-            self.c2, constraint.ValueRangeConstraint(1, 10)
-            )
-
-    def testGoodVal(self):
-        assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
-        assert not self.c1.isSubTypeOf(self.c2) , 'isSubTypeOf failed'
-    def testBadVal(self):
-        assert not self.c2.isSuperTypeOf(self.c1) , 'isSuperTypeOf failed'
-        assert self.c2.isSubTypeOf(self.c1) , 'isSubTypeOf failed'
-        
-if __name__ == '__main__': unittest.main()
-
-# how to apply size constriants to constructed types?
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_namedtype.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from pyasn1.type import namedtype, univ
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class NamedTypeCaseBase(unittest.TestCase):
-    def setUp(self):
-        self.e = namedtype.NamedType('age', univ.Integer())
-    def testIter(self):
-        n, t = self.e
-        assert n == 'age' or t == univ.Integer(), 'unpack fails'
-
-class NamedTypesCaseBase(unittest.TestCase):
-    def setUp(self):
-        self.e = namedtype.NamedTypes(
-            namedtype.NamedType('first-name', univ.OctetString('')),
-            namedtype.OptionalNamedType('age', univ.Integer(0)),
-            namedtype.NamedType('family-name', univ.OctetString(''))
-            )
-    def testIter(self):
-        for t in self.e:
-            break
-        else:
-            assert 0, '__getitem__() fails'
-            
-    def testGetTypeByPosition(self):
-        assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
-               'getTypeByPosition() fails'
-
-    def testGetNameByPosition(self):
-        assert self.e.getNameByPosition(0) == 'first-name', \
-               'getNameByPosition() fails'
-
-    def testGetPositionByName(self):
-        assert self.e.getPositionByName('first-name') == 0, \
-               'getPositionByName() fails'
-
-    def testGetTypesNearPosition(self):
-        assert self.e.getTagMapNearPosition(0).getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString('')
-            }
-        assert self.e.getTagMapNearPosition(1).getPosMap() == {
-            univ.Integer.tagSet: univ.Integer(0),
-            univ.OctetString.tagSet: univ.OctetString('')
-            }
-        assert self.e.getTagMapNearPosition(2).getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString('')
-            }
-
-    def testGetTagMap(self):
-        assert self.e.getTagMap().getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString(''),
-            univ.Integer.tagSet: univ.Integer(0)
-            }
-
-    def testGetTagMapWithDups(self):
-        try:
-            self.e.getTagMap(1)
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'Duped types not noticed'
-        
-    def testGetPositionNearType(self):
-        assert self.e.getPositionNearType(univ.OctetString.tagSet, 0) == 0
-        assert self.e.getPositionNearType(univ.Integer.tagSet, 1) == 1
-        assert self.e.getPositionNearType(univ.OctetString.tagSet, 2) == 2
-
-class OrderedNamedTypesCaseBase(unittest.TestCase):
-    def setUp(self):
-        self.e = namedtype.NamedTypes(
-            namedtype.NamedType('first-name', univ.OctetString('')),
-            namedtype.NamedType('age', univ.Integer(0))
-            )
-            
-    def testGetTypeByPosition(self):
-        assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
-               'getTypeByPosition() fails'
-
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_tag.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from pyasn1.type import tag
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class TagTestCaseBase(unittest.TestCase):
-    def setUp(self):
-        self.t1 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
-        self.t2 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
-    
-class TagCmpTestCase(TagTestCaseBase):
-    def testCmp(self):
-        assert self.t1 == self.t2, 'tag comparation fails'
-
-    def testHash(self):
-        assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails'
-
-    def testSequence(self):
-        assert self.t1[0] == self.t2[0] and \
-               self.t1[1] == self.t2[1] and \
-               self.t1[2] == self.t2[2], 'tag sequence protocol fails'
-
-class TagSetTestCaseBase(unittest.TestCase):
-    def setUp(self):
-        self.ts1 = tag.initTagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
-            )
-        self.ts2 = tag.initTagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
-            )
-
-class TagSetCmpTestCase(TagSetTestCaseBase):
-    def testCmp(self):
-        assert self.ts1 == self.ts2, 'tag set comparation fails'
-
-    def testHash(self):
-        assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails'
-
-    def testLen(self):
-        assert len(self.ts1) == len(self.ts2), 'tag length comparation fails'
-
-class TaggingTestSuite(TagSetTestCaseBase):
-    def testImplicitTag(self):
-        t = self.ts1.tagImplicitly(
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
-            )
-        assert t == tag.TagSet(
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
-            ), 'implicit tagging went wrong'
-
-    def testExplicitTag(self):
-        t = self.ts1.tagExplicitly(
-            tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 32)
-            )
-        assert t == tag.TagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassPrivate, tag.tagFormatConstructed, 32)
-            ), 'explicit tagging went wrong'
-
-class TagSetAddTestSuite(TagSetTestCaseBase):
-    def testAdd(self):
-        t = self.ts1 + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
-        assert t == tag.TagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
-            ), 'TagSet.__add__() fails'
-
-    def testRadd(self):
-        t = tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + self.ts1
-        assert t == tag.TagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
-            ), 'TagSet.__radd__() fails'
-
-class SuperTagSetTestCase(TagSetTestCaseBase):
-    def testSuperTagCheck1(self):
-        assert self.ts1.isSuperTagSetOf(
-            tag.TagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
-            )), 'isSuperTagSetOf() fails'
-
-    def testSuperTagCheck2(self):
-        assert not self.ts1.isSuperTagSetOf(
-            tag.TagSet(
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 13)
-            )), 'isSuperTagSetOf() fails'
-
-    def testSuperTagCheck3(self):
-        assert self.ts1.isSuperTagSetOf(
-            tag.TagSet((), tag.Tag(tag.tagClassUniversal,
-                                   tag.tagFormatSimple, 12))
-            ), 'isSuperTagSetOf() fails'
-    
-if __name__ == '__main__': unittest.main()
deleted file mode 100644
--- a/third_party/python/pyasn1/test/type/test_univ.py
+++ /dev/null
@@ -1,479 +0,0 @@
-from pyasn1.type import univ, tag, constraint, namedtype, namedval, error
-from pyasn1.compat.octets import str2octs, ints2octs
-from pyasn1.error import PyAsn1Error
-from sys import version_info
-if version_info[0:2] < (2, 7) or \
-   version_info[0:2] in ( (3, 0), (3, 1) ):
-    try:
-        import unittest2 as unittest
-    except ImportError:
-        import unittest
-else:
-    import unittest
-
-class IntegerTestCase(unittest.TestCase):
-    def testStr(self): assert str(univ.Integer(1)) in ('1','1L'),'str() fails'
-    def testAnd(self): assert univ.Integer(1) & 0 == 0, '__and__() fails'
-    def testOr(self): assert univ.Integer(1) | 0 == 1, '__or__() fails'
-    def testXor(self): assert univ.Integer(1) ^ 0 == 1, '__xor__() fails'
-    def testRand(self): assert 0 & univ.Integer(1) == 0, '__rand__() fails'
-    def testRor(self): assert 0 | univ.Integer(1) == 1, '__ror__() fails'
-    def testRxor(self): assert 0 ^ univ.Integer(1) == 1, '__rxor__() fails'    
-    def testAdd(self): assert univ.Integer(-4) + 6 == 2, '__add__() fails'
-    def testRadd(self): assert 4 + univ.Integer(5) == 9, '__radd__() fails'
-    def testSub(self): assert univ.Integer(3) - 6 == -3, '__sub__() fails'
-    def testRsub(self): assert 6 - univ.Integer(3) == 3, '__rsub__() fails'
-    def testMul(self): assert univ.Integer(3) * -3 == -9, '__mul__() fails'
-    def testRmul(self): assert 2 * univ.Integer(3) == 6, '__rmul__() fails'
-    def testDiv(self): assert univ.Integer(3) / 2 == 1, '__div__() fails'
-    def testRdiv(self): assert 6 / univ.Integer(3) == 2, '__rdiv__() fails'
-    def testMod(self): assert univ.Integer(3) % 2 == 1, '__mod__() fails'
-    def testRmod(self): assert 4 % univ.Integer(3) == 1, '__rmod__() fails'
-    def testPow(self): assert univ.Integer(3) ** 2 == 9, '__pow__() fails'
-    def testRpow(self): assert 2 ** univ.Integer(2) == 4, '__rpow__() fails'
-    def testLshift(self): assert univ.Integer(1) << 1 == 2, '<< fails'
-    def testRshift(self): assert univ.Integer(2) >> 1 == 1, '>> fails'
-    def testInt(self): assert int(univ.Integer(3)) == 3, '__int__() fails'
-    def testLong(self): assert int(univ.Integer(8)) == 8, '__long__() fails'
-    def testFloat(self): assert float(univ.Integer(4))==4.0,'__float__() fails'
-    def testPrettyIn(self): assert univ.Integer('3') == 3, 'prettyIn() fails'
-    def testTag(self):
-        assert univ.Integer().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
-            )
-    def testNamedVals(self):
-        i = univ.Integer(
-            'asn1', namedValues=univ.Integer.namedValues.clone(('asn1', 1))
-            )
-        assert i == 1, 'named val fails'
-        assert str(i) != 'asn1', 'named val __str__() fails'
-
-class BooleanTestCase(unittest.TestCase):
-    def testTruth(self):
-        assert univ.Boolean(True) and univ.Boolean(1), 'Truth initializer fails'
-    def testFalse(self):
-        assert not univ.Boolean(False) and not univ.Boolean(0), 'False initializer fails'
-    def testStr(self):
-        assert str(univ.Boolean(1)) in ('1', '1L'), 'str() fails'
-    def testTag(self):
-        assert univ.Boolean().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01)
-            )
-    def testConstraints(self):
-        try:
-            univ.Boolean(2)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint fail'
-    def testSubtype(self):
-        assert univ.Integer().subtype(
-            value=1,
-            implicitTag=tag.Tag(tag.tagClassPrivate,tag.tagFormatSimple,2),
-            subtypeSpec=constraint.SingleValueConstraint(1,3)
-            ) == univ.Integer(
-            value=1,
-            tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
-                                        tag.tagFormatSimple,2)),
-            subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1,3))
-            )
-
-class BitStringTestCase(unittest.TestCase):
-    def setUp(self):
-        self.b = univ.BitString(
-            namedValues=namedval.NamedValues(('Active', 0), ('Urgent', 1))
-            )
-    def testSet(self):
-        assert self.b.clone('Active') == (1,)
-        assert self.b.clone("'1010100110001010'B") == (1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,0)
-        assert self.b.clone("'A98A'H") == (1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,0)
-        assert self.b.clone((1,0,1)) == (1,0,1)
-    def testStr(self):
-        assert str(self.b.clone('Urgent,Active')) == '(1, 1)'
-    def testRepr(self):
-        assert repr(self.b.clone('Urgent,Active')) == 'BitString("\'11\'B")'
-    def testTag(self):
-        assert univ.BitString().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
-            )
-    def testLen(self): assert len(self.b.clone("'A98A'H")) == 16
-    def testIter(self):
-        assert self.b.clone("'A98A'H")[0] == 1
-        assert self.b.clone("'A98A'H")[1] == 0
-        assert self.b.clone("'A98A'H")[2] == 1
-        
-class OctetStringTestCase(unittest.TestCase):
-    def testInit(self):
-        assert univ.OctetString(str2octs('abcd')) == str2octs('abcd'), '__init__() fails'
-    def testBinStr(self):
-        assert univ.OctetString(binValue="1000010111101110101111000000111011") == ints2octs((133, 238, 188, 14, 192)), 'bin init fails'
-    def testHexStr(self):
-        assert univ.OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32)), 'hex init fails'
-    def testTuple(self):
-        assert univ.OctetString((1,2,3,4,5)) == ints2octs((1,2,3,4,5)), 'tuple init failed'
-    def testStr(self):
-        assert str(univ.OctetString('q')) == 'q', '__str__() fails'
-    def testSeq(self):
-        assert univ.OctetString('q')[0] == str2octs('q')[0],'__getitem__() fails'
-    def testAsOctets(self):
-        assert univ.OctetString('abcd').asOctets() == str2octs('abcd'), 'testAsOctets() fails'
-    def testAsInts(self):
-        assert univ.OctetString('abcd').asNumbers() == (97, 98, 99, 100), 'testAsNumbers() fails'
-
-    def testEmpty(self):
-        try:
-            str(univ.OctetString())
-        except PyAsn1Error:
-            pass
-        else:
-            assert 0, 'empty OctetString() not reported'
-            
-    def testAdd(self):
-        assert univ.OctetString('') + 'q' == str2octs('q'), '__add__() fails'
-    def testRadd(self):
-        assert 'b' + univ.OctetString('q') == str2octs('bq'), '__radd__() fails'
-    def testMul(self):
-        assert univ.OctetString('a') * 2 == str2octs('aa'), '__mul__() fails'
-    def testRmul(self):
-        assert 2 * univ.OctetString('b') == str2octs('bb'), '__rmul__() fails'
-    def testTag(self):
-        assert univ.OctetString().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
-            )
-
-class Null(unittest.TestCase):
-    def testStr(self): assert str(univ.Null('')) == '', 'str() fails'
-    def testTag(self):
-        assert univ.Null().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
-            )
-    def testConstraints(self):
-        try:
-            univ.Null(2)
-        except error.ValueConstraintError:
-            pass
-        else:
-            assert 0, 'constraint fail'
-
-class RealTestCase(unittest.TestCase):
-    def testStr(self): assert str(univ.Real(1.0)) == '1.0','str() fails'
-    def testRepr(self): assert repr(univ.Real(-4.1)) == 'Real((-41, 10, -1))','repr() fails'
-    def testAdd(self): assert univ.Real(-4.1) + 1.4 == -2.7, '__add__() fails'
-    def testRadd(self): assert 4 + univ.Real(0.5) == 4.5, '__radd__() fails'
-    def testSub(self): assert univ.Real(3.9) - 1.7 == 2.2, '__sub__() fails'
-    def testRsub(self): assert 6.1 - univ.Real(0.1) == 6, '__rsub__() fails'
-    def testMul(self): assert univ.Real(3.0) * -3 == -9, '__mul__() fails'
-    def testRmul(self): assert 2 * univ.Real(3.0) == 6, '__rmul__() fails'
-    def testDiv(self): assert univ.Real(3.0) / 2 == 1.5, '__div__() fails'
-    def testRdiv(self): assert 6 / univ.Real(3.0) == 2, '__rdiv__() fails'
-    def testMod(self): assert univ.Real(3.0) % 2 == 1, '__mod__() fails'
-    def testRmod(self): assert 4 % univ.Real(3.0) == 1, '__rmod__() fails'
-    def testPow(self): assert univ.Real(3.0) ** 2 == 9, '__pow__() fails'
-    def testRpow(self): assert 2 ** univ.Real(2.0) == 4, '__rpow__() fails'
-    def testInt(self): assert int(univ.Real(3.0)) == 3, '__int__() fails'
-    def testLong(self): assert int(univ.Real(8.0)) == 8, '__long__() fails'
-    def testFloat(self): assert float(univ.Real(4.0))==4.0,'__float__() fails'
-    def testPrettyIn(self): assert univ.Real((3,10,0)) == 3, 'prettyIn() fails'
-    # infinite float values
-    def testStrInf(self):
-        assert str(univ.Real('inf')) == 'inf','str() fails'
-    def testReprInf(self):
-        assert repr(univ.Real('inf')) == 'Real(\'inf\')','repr() fails'
-    def testAddInf(self):
-        assert univ.Real('inf') + 1 == float('inf'), '__add__() fails'
-    def testRaddInf(self):
-        assert 1 + univ.Real('inf') == float('inf'), '__radd__() fails'
-    def testIntInf(self):
-        try:
-            assert int(univ.Real('inf'))
-        except OverflowError:
-            pass
-        else:
-            assert 0, '__int__() fails'
-    def testLongInf(self):
-        try:
-            assert int(univ.Real('inf'))
-        except OverflowError:
-            pass
-        else:
-            assert 0, '__long__() fails'        
-        assert int(univ.Real(8.0)) == 8, '__long__() fails'
-    def testFloatInf(self):
-        assert float(univ.Real('-inf')) == float('-inf'),'__float__() fails'
-    def testPrettyInInf(self):
-        assert univ.Real(float('inf')) == float('inf'), 'prettyIn() fails'
-    def testPlusInf(self):
-        assert univ.Real('inf').isPlusInfinity(), 'isPlusInfinity failed'
-    def testMinusInf(self):
-        assert univ.Real('-inf').isMinusInfinity(), 'isMinusInfinity failed'
-
-    def testTag(self):
-        assert univ.Real().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
-            )
-
-class ObjectIdentifier(unittest.TestCase):
-    def testStr(self):
-        assert str(univ.ObjectIdentifier((1,3,6))) == '1.3.6'
-    def testEq(self):
-        assert univ.ObjectIdentifier((1,3,6)) == (1,3,6), '__cmp__() fails'
-    def testAdd(self):
-        assert univ.ObjectIdentifier((1,3)) + (6,)==(1,3,6),'__add__() fails'
-    def testRadd(self):
-        assert (1,) + univ.ObjectIdentifier((3,6))==(1,3,6),'__radd__() fails'
-    def testLen(self):
-        assert len(univ.ObjectIdentifier((1,3))) == 2,'__len__() fails'
-    def testPrefix(self):
-        o = univ.ObjectIdentifier('1.3.6')
-        assert o.isPrefixOf((1,3,6)), 'isPrefixOf() fails'
-        assert o.isPrefixOf((1,3,6,1)), 'isPrefixOf() fails'
-        assert not o.isPrefixOf((1,3)), 'isPrefixOf() fails'        
-    def testInput(self):
-        assert univ.ObjectIdentifier('1.3.6')==(1,3,6),'prettyIn() fails'
-    def testTag(self):
-        assert univ.ObjectIdentifier().getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
-            )
-
-class SequenceOf(unittest.TestCase):
-    def setUp(self):
-        self.s1 = univ.SequenceOf(
-            componentType=univ.OctetString('')
-            )
-        self.s2 = self.s1.clone()
-    def testTag(self):
-        assert self.s1.getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
-            ), 'wrong tagSet'
-    def testSeq(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
-        assert self.s1[0] == str2octs('abc'), 'set by idx fails'
-        self.s1[0] = 'cba'
-        assert self.s1[0] == str2octs('cba'), 'set by idx fails'
-    def testCmp(self):
-        self.s1.clear()
-        self.s1.setComponentByPosition(0, 'abc')
-        self.s2.clear()
-        self.s2.setComponentByPosition(0, univ.OctetString('abc'))
-        assert self.s1 == self.s2, '__cmp__() fails'
-    def testSubtypeSpec(self):
-        s = self.s1.clone(subtypeSpec=constraint.ConstraintsUnion(
-            constraint.SingleValueConstraint(str2octs('abc'))
-            ))
-        try:
-            s.setComponentByPosition(0, univ.OctetString('abc'))
-        except:
-            assert 0, 'constraint fails'
-        try:
-            s.setComponentByPosition(1, univ.OctetString('Abc'))
-        except:
-            pass
-        else:
-            assert 0, 'constraint fails'
-    def testSizeSpec(self):
-        s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion(
-            constraint.ValueSizeConstraint(1,1)
-            ))
-        s.setComponentByPosition(0, univ.OctetString('abc'))
-        try:
-            s.verifySizeSpec()
-        except:
-            assert 0, 'size spec fails'
-        s.setComponentByPosition(1, univ.OctetString('abc'))
-        try:
-            s.verifySizeSpec()
-        except:
-            pass
-        else:
-            assert 0, 'size spec fails'
-    def testGetComponentTagMap(self):
-        assert self.s1.getComponentTagMap().getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString('')
-            }
-    def testSubtype(self):
-        self.s1.clear()
-        assert self.s1.subtype(
-            implicitTag=tag.Tag(tag.tagClassPrivate,tag.tagFormatSimple,2),
-            subtypeSpec=constraint.SingleValueConstraint(1,3),
-            sizeSpec=constraint.ValueSizeConstraint(0,1)
-            ) == self.s1.clone(
-            tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
-                                        tag.tagFormatSimple,2)),
-            subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1,3)),
-            sizeSpec=constraint.ValueSizeConstraint(0,1)
-            )
-    def testClone(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
-        s = self.s1.clone()
-        assert len(s) == 0
-        s = self.s1.clone(cloneValueFlag=1)
-        assert len(s) == 1
-        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
-        
-class Sequence(unittest.TestCase):
-    def setUp(self):
-        self.s1 = univ.Sequence(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('name', univ.OctetString('')),
-            namedtype.OptionalNamedType('nick', univ.OctetString('')),
-            namedtype.DefaultedNamedType('age', univ.Integer(34))
-            ))
-    def testTag(self):
-        assert self.s1.getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
-            ), 'wrong tagSet'
-    def testById(self):
-        self.s1.setComponentByName('name', univ.OctetString('abc'))
-        assert self.s1.getComponentByName('name') == str2octs('abc'), 'set by name fails'
-    def testByKey(self):
-        self.s1['name'] = 'abc'
-        assert self.s1['name'] == str2octs('abc'), 'set by key fails'
-    def testGetNearPosition(self):
-        assert self.s1.getComponentTagMapNearPosition(1).getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString(''),
-            univ.Integer.tagSet: univ.Integer(34)
-            }
-        assert self.s1.getComponentPositionNearType(
-            univ.OctetString.tagSet, 1
-            ) == 1
-    def testGetDefaultComponentByPosition(self):
-        self.s1.clear()
-        assert self.s1.getDefaultComponentByPosition(0) == None
-        assert self.s1.getDefaultComponentByPosition(2) == univ.Integer(34)
-    def testSetDefaultComponents(self):
-        self.s1.clear()
-        assert self.s1.getComponentByPosition(2) == None
-        self.s1.setComponentByPosition(0, univ.OctetString('Ping'))
-        self.s1.setComponentByPosition(1, univ.OctetString('Pong'))
-        self.s1.setDefaultComponents()
-        assert self.s1.getComponentByPosition(2) == 34
-    def testClone(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
-        self.s1.setComponentByPosition(1, univ.OctetString('def'))
-        self.s1.setComponentByPosition(2, univ.Integer(123))
-        s = self.s1.clone()
-        assert s.getComponentByPosition(0) != self.s1.getComponentByPosition(0)
-        assert s.getComponentByPosition(1) != self.s1.getComponentByPosition(1)
-        assert s.getComponentByPosition(2) != self.s1.getComponentByPosition(2)
-        s = self.s1.clone(cloneValueFlag=1)
-        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
-        assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1)
-        assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2)
-
-class SetOf(unittest.TestCase):
-    def setUp(self):
-        self.s1 = univ.SetOf(componentType=univ.OctetString(''))
-    def testTag(self):
-        assert self.s1.getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
-            ), 'wrong tagSet'
-    def testSeq(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
-        assert self.s1[0] == str2octs('abc'), 'set by idx fails'
-        self.s1.setComponentByPosition(0, self.s1[0].clone('cba'))
-        assert self.s1[0] == str2octs('cba'), 'set by idx fails'
-
-class Set(unittest.TestCase):
-    def setUp(self):
-        self.s1 = univ.Set(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('name', univ.OctetString('')),
-            namedtype.OptionalNamedType('null', univ.Null('')),
-            namedtype.DefaultedNamedType('age', univ.Integer(34))
-            ))
-        self.s2 = self.s1.clone()
-    def testTag(self):
-        assert self.s1.getTagSet() == tag.TagSet(
-            (),
-            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
-            ), 'wrong tagSet'
-    def testByTypeWithPythonValue(self):
-        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
-        assert self.s1.getComponentByType(
-            univ.OctetString.tagSet
-            ) == str2octs('abc'), 'set by name fails'
-    def testByTypeWithInstance(self):
-        self.s1.setComponentByType(univ.OctetString.tagSet, univ.OctetString('abc'))
-        assert self.s1.getComponentByType(
-            univ.OctetString.tagSet
-            ) == str2octs('abc'), 'set by name fails'
-    def testGetTagMap(self):
-        assert self.s1.getTagMap().getPosMap() == {
-            univ.Set.tagSet: univ.Set()
-            }
-    def testGetComponentTagMap(self):
-        assert self.s1.getComponentTagMap().getPosMap() == {
-            univ.OctetString.tagSet: univ.OctetString(''),
-            univ.Null.tagSet: univ.Null(''),
-            univ.Integer.tagSet: univ.Integer(34)
-            }
-    def testGetPositionByType(self):
-        assert self.s1.getComponentPositionByType(
-            univ.Null().getTagSet()
-            ) == 1
-
-class Choice(unittest.TestCase):
-    def setUp(self):
-        innerComp = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('count', univ.Integer()),
-            namedtype.NamedType('flag', univ.Boolean())
-            ))
-        self.s1 = univ.Choice(componentType=namedtype.NamedTypes(
-            namedtype.NamedType('name', univ.OctetString()),
-            namedtype.NamedType('sex', innerComp)
-            ))
-    def testTag(self):
-        assert self.s1.getTagSet() == tag.TagSet(), 'wrong tagSet'
-    def testOuterByTypeWithPythonValue(self):
-        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
-        assert self.s1.getComponentByType(
-            univ.OctetString.tagSet
-            ) == str2octs('abc')
-    def testOuterByTypeWithInstanceValue(self):
-        self.s1.setComponentByType(
-            univ.OctetString.tagSet, univ.OctetString('abc')
-            )
-        assert self.s1.getComponentByType(
-            univ.OctetString.tagSet
-            ) == str2octs('abc')
-    def testInnerByTypeWithPythonValue(self):
-        self.s1.setComponentByType(univ.Integer.tagSet, 123, 1)
-        assert self.s1.getComponentByType(
-            univ.Integer.tagSet, 1
-            ) == 123
-    def testInnerByTypeWithInstanceValue(self):
-        self.s1.setComponentByType(
-            univ.Integer.tagSet, univ.Integer(123), 1
-            )
-        assert self.s1.getComponentByType(
-            univ.Integer.tagSet, 1
-            ) == 123
-    def testCmp(self):
-        self.s1.setComponentByName('name', univ.OctetString('abc'))
-        assert self.s1 == str2octs('abc'), '__cmp__() fails'
-    def testGetComponent(self):
-        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
-        assert self.s1.getComponent() == str2octs('abc'), 'getComponent() fails'
-    def testGetName(self):
-        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
-        assert self.s1.getName() == 'name', 'getName() fails'
-    def testSetComponentByPosition(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('Jim'))
-        assert self.s1 == str2octs('Jim')
-    def testClone(self):
-        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
-        s = self.s1.clone()
-        assert len(s) == 0
-        s = self.s1.clone(cloneValueFlag=1)
-        assert len(s) == 1
-        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
-        
-if __name__ == '__main__': unittest.main()
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/__main__.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.test_debug.suite',
+     'tests.type.__main__.suite',
+     'tests.codec.__main__.suite',
+     'tests.compat.__main__.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/base.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from pyasn1 import debug
+
+
+class BaseTestCase(unittest.TestCase):
+
+    def setUp(self):
+        debug.setLogger(debug.Debug('all', printer=lambda *x: None))
+
+    def tearDown(self):
+        debug.setLogger(None)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/__main__.py
@@ -0,0 +1,22 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.codec.ber.__main__.suite',
+     'tests.codec.cer.__main__.suite',
+     'tests.codec.der.__main__.suite',
+     'tests.codec.native.__main__.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/ber/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.codec.ber.test_encoder.suite',
+     'tests.codec.ber.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/test_decoder.py
@@ -0,0 +1,1294 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag, namedtype, univ, char
+from pyasn1.codec.ber import decoder, eoo
+from pyasn1.compat.octets import ints2octs, str2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class LargeTagDecoderTestCase(BaseTestCase):
+    def testLargeTag(self):
+        assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null)
+
+    def testLongTag(self):
+        assert decoder.decode(ints2octs((0x1f, 2, 1, 0)))[0].tagSet == univ.Integer.tagSet
+
+    def testTagsEquivalence(self):
+        integer = univ.Integer(2).subtype(implicitTag=tag.Tag(tag.tagClassContext, 0, 0))
+        assert decoder.decode(ints2octs((0x9f, 0x80, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) == decoder.decode(
+            ints2octs((0x9f, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer)
+
+
+class DecoderCacheTestCase(BaseTestCase):
+    def testCache(self):
+        assert decoder.decode(ints2octs((0x1f, 2, 1, 0))) == decoder.decode(ints2octs((0x1f, 2, 1, 0)))
+
+
+class IntegerDecoderTestCase(BaseTestCase):
+    def testPosInt(self):
+        assert decoder.decode(ints2octs((2, 1, 12))) == (12, null)
+
+    def testNegInt(self):
+        assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null)
+
+    def testZero(self):
+        assert decoder.decode(ints2octs((2, 0))) == (0, null)
+
+    def testZeroLong(self):
+        assert decoder.decode(ints2octs((2, 1, 0))) == (0, null)
+
+    def testMinusOne(self):
+        assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null)
+
+    def testPosLong(self):
+        assert decoder.decode(
+            ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
+        ) == (0xffffffffffffffff, null)
+
+    def testNegLong(self):
+        assert decoder.decode(
+            ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
+        ) == (-0xffffffffffffffff, null)
+
+    def testSpec(self):
+        try:
+            decoder.decode(
+                ints2octs((2, 1, 12)), asn1Spec=univ.Null()
+            ) == (12, null)
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong asn1Spec worked out'
+        assert decoder.decode(
+            ints2octs((2, 1, 12)), asn1Spec=univ.Integer()
+        ) == (12, null)
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(ints2octs((34, 1, 12)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert decoder.decode(ints2octs((1, 1, 1))) == (1, null)
+
+    def testTrueNeg(self):
+        assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
+
+    def testExtraTrue(self):
+        assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50)))
+
+    def testFalse(self):
+        assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(ints2octs((33, 1, 1)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((3, 3, 1, 169, 138))
+        ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((3, 3, 1, 169, 138))
+        ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+        ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+        ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null)
+
+    def testDefModeChunkedSubst(self):
+        assert decoder.decode(
+            ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)),
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), str2octs(''))
+
+    def testIndefModeChunkedSubst(self):
+        assert decoder.decode(
+            ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)),
+            substrateFun=lambda a, b, c: (b, str2octs(''))
+        ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), str2octs(''))
+
+    def testTypeChecking(self):
+        try:
+            decoder.decode(ints2octs((35, 4, 2, 2, 42, 42)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'accepted mis-encoded bit-string constructed out of an integer'
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+        ) == (str2octs('Quick brown fox'), null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+        ) == (str2octs('Quick brown fox'), null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs(
+                (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
+        ) == (str2octs('Quick brown fox'), null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111,
+                       120, 0, 0))
+        ) == (str2octs('Quick brown fox'), null)
+
+    def testDefModeChunkedSubst(self):
+        assert decoder.decode(
+            ints2octs(
+                (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)),
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), str2octs(''))
+
+    def testIndefModeChunkedSubst(self):
+        assert decoder.decode(
+            ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111,
+                       120, 0, 0)),
+            substrateFun=lambda a, b, c: (b, str2octs(''))
+        ) == (ints2octs(
+            (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), str2octs(''))
+
+
+class ExpTaggedOctetStringDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.o = univ.OctetString(
+            'Quick brown fox',
+            tagSet=univ.OctetString.tagSet.tagExplicitly(
+                tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
+            ))
+
+    def testDefMode(self):
+        o, r = decoder.decode(
+            ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+        )
+        assert not r
+        assert self.o == o
+        assert self.o.tagSet == o.tagSet
+        assert self.o.isSameTypeWith(o)
+
+    def testIndefMode(self):
+        o, r = decoder.decode(
+            ints2octs((101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0))
+        )
+        assert not r
+        assert self.o == o
+        assert self.o.tagSet == o.tagSet
+        assert self.o.isSameTypeWith(o)
+
+    def testDefModeChunked(self):
+        o, r = decoder.decode(
+            ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120))
+        )
+        assert not r
+        assert self.o == o
+        assert self.o.tagSet == o.tagSet
+        assert self.o.isSameTypeWith(o)
+
+    def testIndefModeChunked(self):
+        o, r = decoder.decode(
+            ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
+        )
+        assert not r
+        assert self.o == o
+        assert self.o.tagSet == o.tagSet
+        assert self.o.isSameTypeWith(o)
+
+    def testDefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), str2octs(''))
+
+    def testIndefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((
+                      101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0,
+                      0, 0, 0)),
+            substrateFun=lambda a, b, c: (b, str2octs(''))
+        ) == (ints2octs(
+            (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), str2octs(''))
+
+
+class NullDecoderTestCase(BaseTestCase):
+    def testNull(self):
+        assert decoder.decode(ints2octs((5, 0))) == (null, null)
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(ints2octs((37, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+
+# Useful analysis of OID encoding issues could be found here:
+# http://www.viathinksoft.de/~daniel-marschall/asn.1/oid_facts.html
+class ObjectIdentifierDecoderTestCase(BaseTestCase):
+    def testOne(self):
+        assert decoder.decode(
+            ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+        ) == ((1, 3, 6, 0, 0xffffe), null)
+
+    def testEdge1(self):
+        assert decoder.decode(
+            ints2octs((6, 1, 39))
+        ) == ((0, 39), null)
+
+    def testEdge2(self):
+        assert decoder.decode(
+            ints2octs((6, 1, 79))
+        ) == ((1, 39), null)
+
+    def testEdge3(self):
+        assert decoder.decode(
+            ints2octs((6, 1, 120))
+        ) == ((2, 40), null)
+
+    def testEdge4(self):
+        assert decoder.decode(
+            ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F))
+        ) == ((2, 0xffffffff), null)
+
+    def testEdge5(self):
+        assert decoder.decode(
+            ints2octs((6, 1, 0x7F))
+        ) == ((2, 47), null)
+
+    def testEdge6(self):
+        assert decoder.decode(
+            ints2octs((6, 2, 0x81, 0x00))
+        ) == ((2, 48), null)
+
+    def testEdge7(self):
+        assert decoder.decode(
+            ints2octs((6, 3, 0x81, 0x34, 0x03))
+        ) == ((2, 100, 3), null)
+
+    def testEdge8(self):
+        assert decoder.decode(
+            ints2octs((6, 2, 133, 0))
+        ) == ((2, 560), null)
+
+    def testEdge9(self):
+        assert decoder.decode(
+            ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02))
+        ) == ((2, 16843570), null)
+
+    def testNonLeading0x80(self):
+        assert decoder.decode(
+            ints2octs((6, 5, 85, 4, 129, 128, 0)),
+        ) == ((2, 5, 4, 16384), null)
+
+    def testLeading0x80Case1(self):
+        try:
+            decoder.decode(
+                ints2octs((6, 5, 85, 4, 128, 129, 0))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Leading 0x80 tolarated'
+
+    def testLeading0x80Case2(self):
+        try:
+            decoder.decode(
+                ints2octs((6, 7, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7F))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Leading 0x80 tolarated'
+
+    def testLeading0x80Case3(self):
+        try:
+            decoder.decode(
+                ints2octs((6, 2, 0x80, 1))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Leading 0x80 tolarated'
+
+    def testLeading0x80Case4(self):
+        try:
+            decoder.decode(
+                ints2octs((6, 2, 0x80, 0x7F))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Leading 0x80 tolarated'
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(ints2octs((38, 1, 239)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+    def testZeroLength(self):
+        try:
+            decoder.decode(ints2octs((6, 0, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'zero length tolarated'
+
+    def testIndefiniteLength(self):
+        try:
+            decoder.decode(ints2octs((6, 128, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'indefinite length tolarated'
+
+    def testReservedLength(self):
+        try:
+            decoder.decode(ints2octs((6, 255, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'reserved length tolerated'
+
+    def testLarge1(self):
+        assert decoder.decode(
+            ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB,
+                       0xE2, 0xB7, 0x17))
+        ) == ((2, 18446744073709551535184467440737095), null)
+
+    def testLarge2(self):
+        assert decoder.decode(
+            ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6,
+                       0xB8, 0xCB, 0xE2, 0xB6, 0x47))
+        ) == ((2, 999, 18446744073709551535184467440737095), null)
+
+
+class RealDecoderTestCase(BaseTestCase):
+    def testChar(self):
+        assert decoder.decode(
+            ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
+        ) == (univ.Real((123, 10, 11)), null)
+
+    def testBin1(self):  # check base = 2
+        assert decoder.decode(  # (0.5, 2, 0) encoded with base = 2
+            ints2octs((9, 3, 128, 255, 1))
+        ) == (univ.Real((1, 2, -1)), null)
+
+    def testBin2(self):  # check base = 2 and scale factor
+        assert decoder.decode(  # (3.25, 2, 0) encoded with base = 8
+            ints2octs((9, 3, 148, 255, 13))
+        ) == (univ.Real((26, 2, -3)), null)
+
+    def testBin3(self):  # check base = 16
+        assert decoder.decode(  # (0.00390625, 2, 0) encoded with base = 16
+            ints2octs((9, 3, 160, 254, 1))
+        ) == (univ.Real((1, 2, -8)), null)
+
+    def testBin4(self):  # check exponenta = 0
+        assert decoder.decode(  # (1, 2, 0) encoded with base = 2
+            ints2octs((9, 3, 128, 0, 1))
+        ) == (univ.Real((1, 2, 0)), null)
+
+    def testBin5(self):  # case of 2 octs for exponenta and negative exponenta
+        assert decoder.decode(  # (3, 2, -1020) encoded with base = 16
+            ints2octs((9, 4, 161, 255, 1, 3))
+        ) == (univ.Real((3, 2, -1020)), null)
+
+# TODO: this requires Real type comparison fix
+
+#    def testBin6(self):
+#        assert decoder.decode(
+#            ints2octs((9, 5, 162, 0, 255, 255, 1))
+#        ) == (univ.Real((1, 2, 262140)), null)
+
+#    def testBin7(self):
+#        assert decoder.decode(
+#            ints2octs((9, 7, 227, 4, 1, 35, 69, 103, 1))
+#        ) == (univ.Real((-1, 2, 76354972)), null)
+
+    def testPlusInf(self):
+        assert decoder.decode(
+            ints2octs((9, 1, 64))
+        ) == (univ.Real('inf'), null)
+
+    def testMinusInf(self):
+        assert decoder.decode(
+            ints2octs((9, 1, 65))
+        ) == (univ.Real('-inf'), null)
+
+    def testEmpty(self):
+        assert decoder.decode(
+            ints2octs((9, 0))
+        ) == (univ.Real(0.0), null)
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(ints2octs((41, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+    def testShortEncoding(self):
+        try:
+            decoder.decode(ints2octs((9, 1, 131)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'accepted too-short real'
+
+
+if sys.version_info[0:2] > (2, 5):
+    class UniversalStringDecoderTestCase(BaseTestCase):
+        def testDecoder(self):
+            assert decoder.decode(ints2octs((28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99))) == (char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class BMPStringDecoderTestCase(BaseTestCase):
+    def testDecoder(self):
+        assert decoder.decode(ints2octs((30, 6, 0, 97, 0, 98, 0, 99))) == (char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class UTF8StringDecoderTestCase(BaseTestCase):
+    def testDecoder(self):
+        assert decoder.decode(ints2octs((12, 3, 97, 98, 99))) == (char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null)
+
+
+class SequenceOfDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.SequenceOf(componentType=univ.OctetString())
+        self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+        ) == (self.s, null)
+
+    def testSchemalessDecoder(self):
+        assert decoder.decode(
+            ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=univ.SequenceOf()
+        ) == (self.s, null)
+
+
+class ExpTaggedSequenceOfDecoderTestCase(BaseTestCase):
+
+    def testWithSchema(self):
+        s = univ.SequenceOf().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))
+        s2, r = decoder.decode(
+            ints2octs((163, 15, 48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=s
+        )
+        assert not r
+        assert s2 == [str2octs('quick brown')]
+        assert s.tagSet == s2.tagSet
+
+    def testWithoutSchema(self):
+        s = univ.SequenceOf().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))
+        s2, r = decoder.decode(
+            ints2octs((163, 15, 48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+        )
+        assert not r
+        assert s2 == [str2octs('quick brown')]
+        assert s.tagSet == s2.tagSet
+
+
+class SequenceOfDecoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SequenceOf(componentType=univ.OctetString())
+        self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+
+class SetOfDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SetOf(componentType=univ.OctetString())
+        self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+        ) == (self.s, null)
+
+    def testSchemalessDecoder(self):
+        assert decoder.decode(
+            ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=univ.SetOf()
+        ) == (self.s, null)
+
+
+class SetOfDecoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SetOf(componentType=univ.OctetString())
+        self.s.setComponentByPosition(0, univ.OctetString('quick brown'))
+
+    def testDefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+
+class SequenceDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.NamedType('first-name', univ.OctetString(null)),
+                namedtype.NamedType('age', univ.Integer(33))
+            )
+        )
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs(
+                (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs(''))
+
+    def testWithOptionalAndDefaultedIndefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
+            substrateFun=lambda a, b, c: (b, str2octs(''))
+        ) == (ints2octs(
+            (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs(''))
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(
+                ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+
+class SequenceDecoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((48, 2, 5, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalDefMode(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionaIndefMode(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)),
+            asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalDefModeChunked(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)),
+            asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalIndefModeChunked(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+                       0, 0, 0)),
+            asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedDefMode(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedDefModeChunked(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedIndefModeChunked(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+            asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1,
+                       0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs(
+                (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)),
+            asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+                       0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+
+class SetDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.NamedType('first-name', univ.OctetString(null)),
+                namedtype.NamedType('age', univ.Integer(33))
+            )
+        )
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        assert decoder.decode(
+            ints2octs(
+                (49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)),
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), str2octs(''))
+
+    def testWithOptionalAndDefaultedIndefModeSubst(self):
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)),
+            substrateFun=lambda a, b, c: (b, str2octs(''))
+        ) == (ints2octs(
+            (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), str2octs(''))
+
+    def testTagFormat(self):
+        try:
+            decoder.decode(
+                ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'wrong tagFormat worked out'
+
+
+class SetDecoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefMode(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((49, 2, 5, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalDefMode(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((49, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionaIndefMode(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalDefModeChunked(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((49, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalIndefModeChunked(self):
+        self.__initWithOptional()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedDefMode(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedDefModeChunked(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithDefaultedIndefModeChunked(self):
+        self.__initWithDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeReordered(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 18, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefModeReordered(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 128, 2, 1, 1, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0,  0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert decoder.decode(
+            ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+
+class SequenceOfWithExpTaggedOctetStringDecoder(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SequenceOf(
+            componentType=univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
+        )
+        self.s.setComponentByPosition(0, 'q')
+        self.s2 = univ.SequenceOf()
+
+    def testDefModeSchema(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeSchema(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testDefModeNoComponent(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s2)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeNoComponent(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s2)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testDefModeSchemaless(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)))
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeSchemaless(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)))
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+
+class SequenceWithExpTaggedOctetStringDecoder(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType(
+                    'x', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))
+                )
+            )
+        )
+        self.s.setComponentByPosition(0, 'q')
+        self.s2 = univ.Sequence()
+
+    def testDefModeSchema(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeSchema(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testDefModeNoComponent(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)), asn1Spec=self.s2)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeNoComponent(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)), asn1Spec=self.s2)
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testDefModeSchemaless(self):
+        s, r = decoder.decode(ints2octs((48, 5, 163, 3, 4, 1, 113)))
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+    def testIndefModeSchemaless(self):
+        s, r = decoder.decode(ints2octs((48, 128, 163, 128, 4, 1, 113, 0, 0, 0, 0)))
+        assert not r
+        assert s == self.s
+        assert s.tagSet == self.s.tagSet
+
+
+class ChoiceDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.NamedType('number', univ.Integer(0)),
+                namedtype.NamedType('string', univ.OctetString())
+            )
+        )
+
+    def testBySpec(self):
+        self.s.setComponentByPosition(0, univ.Null(null))
+        assert decoder.decode(
+            ints2octs((5, 0)), asn1Spec=self.s
+        ) == (self.s, null)
+
+    def testWithoutSpec(self):
+        self.s.setComponentByPosition(0, univ.Null(null))
+        assert decoder.decode(ints2octs((5, 0))) == (self.s, null)
+        assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null)
+
+    def testUndefLength(self):
+        self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+        assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)),
+                              asn1Spec=self.s) == (self.s, null)
+
+    def testExplicitTag(self):
+        s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
+                                               tag.tagFormatConstructed, 4))
+        s.setComponentByPosition(0, univ.Null(null))
+        assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null)
+
+    def testExplicitTagUndefLength(self):
+        s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext,
+                                               tag.tagFormatConstructed, 4))
+        s.setComponentByPosition(0, univ.Null(null))
+        assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null)
+
+
+class AnyDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Any()
+
+    def testByUntagged(self):
+        assert decoder.decode(
+            ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
+        ) == (univ.Any('\004\003fox'), null)
+
+    def testTaggedEx(self):
+        s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+        assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
+
+    def testTaggedIm(self):
+        s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+        assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null)
+
+    def testByUntaggedIndefMode(self):
+        assert decoder.decode(
+            ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s
+        ) == (univ.Any('\004\003fox'), null)
+
+    def testTaggedExIndefMode(self):
+        s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+        assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
+
+    def testTaggedImIndefMode(self):
+        s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
+        assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
+
+    def testByUntaggedSubst(self):
+        assert decoder.decode(
+            ints2octs((4, 3, 102, 111, 120)),
+            asn1Spec=self.s,
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((4, 3, 102, 111, 120)), str2octs(''))
+
+    def testTaggedExSubst(self):
+        assert decoder.decode(
+            ints2octs((164, 5, 4, 3, 102, 111, 120)),
+            asn1Spec=self.s,
+            substrateFun=lambda a, b, c: (b, b[c:])
+        ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), str2octs(''))
+
+
+class EndOfOctetsTestCase(BaseTestCase):
+    def testUnexpectedEoo(self):
+        try:
+            decoder.decode(ints2octs((0, 0)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'end-of-contents octets accepted at top level'
+
+    def testExpectedEoo(self):
+        result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True)
+        assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets and result is eoo.endOfOctets
+        assert remainder == null
+
+    def testDefiniteNoEoo(self):
+        try:
+            decoder.decode(ints2octs((0x23, 0x02, 0x00, 0x00)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'end-of-contents octets accepted inside definite-length encoding'
+
+    def testIndefiniteEoo(self):
+        result, remainder = decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x00)))
+        assert result == () and remainder == null, 'incorrect decoding of indefinite length end-of-octets'
+
+    def testNoLongFormEoo(self):
+        try:
+            decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x81, 0x00)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'end-of-contents octets accepted with invalid long-form length'
+
+    def testNoConstructedEoo(self):
+        try:
+            decoder.decode(ints2octs((0x23, 0x80, 0x20, 0x00)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'end-of-contents octets accepted with invalid constructed encoding'
+
+    def testNoEooData(self):
+        try:
+            decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x01, 0x00)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'end-of-contents octets accepted with unexpected data'
+
+
+class NonStringDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null(null)),
+                namedtype.NamedType('first-name', univ.OctetString(null)),
+                namedtype.NamedType('age', univ.Integer(33))
+            )
+        )
+        self.s.setComponentByPosition(0, univ.Null(null))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+        self.substrate = ints2octs([48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1])
+
+    def testOctetString(self):
+        s, _ = decoder.decode(univ.OctetString(self.substrate), asn1Spec=self.s)
+        assert self.s == s
+
+    def testAny(self):
+        s, _ = decoder.decode(univ.Any(self.substrate), asn1Spec=self.s)
+        assert self.s == s
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/ber/test_encoder.py
@@ -0,0 +1,940 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag, namedtype, univ, char
+from pyasn1.codec.ber import encoder
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class LargeTagEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.o = univ.Integer().subtype(
+            value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf)
+        )
+
+    def testEncoder(self):
+        assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))
+
+
+class IntegerEncoderTestCase(BaseTestCase):
+    def testPosInt(self):
+        assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12))
+
+    def testNegInt(self):
+        assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244))
+
+    def testZero(self):
+        assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0))
+
+    def testCompactZero(self):
+        encoder.IntegerEncoder.supportCompactZero = True
+        substrate = encoder.encode(univ.Integer(0))
+        encoder.IntegerEncoder.supportCompactZero = False
+        assert substrate == ints2octs((2, 0))
+
+    def testMinusOne(self):
+        assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255))
+
+    def testPosLong(self):
+        assert encoder.encode(
+            univ.Integer(0xffffffffffffffff)
+        ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255))
+
+    def testNegLong(self):
+        assert encoder.encode(
+            univ.Integer(-0xffffffffffffffff)
+        ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1))
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1))
+
+    def testFalse(self):
+        assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1))
+
+    def testDefMode(self):
+        assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.b, defMode=False
+        ) == ints2octs((3, 3, 1, 169, 138))
+
+    def testDefModeChunked(self):
+        assert encoder.encode(
+            self.b, maxChunkSize=1
+        ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+
+    def testIndefModeChunked(self):
+        assert encoder.encode(
+            self.b, defMode=False, maxChunkSize=1
+        ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+
+    def testEmptyValue(self):
+        assert encoder.encode(univ.BitString([])) == ints2octs((3, 1, 0))
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.o = univ.OctetString('Quick brown fox')
+
+    def testDefMode(self):
+        assert encoder.encode(self.o) == ints2octs(
+            (4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.o, defMode=False
+        ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+    def testDefModeChunked(self):
+        assert encoder.encode(
+            self.o, maxChunkSize=4
+        ) == ints2octs((36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119,
+                        110, 32, 4, 3, 102, 111, 120))
+
+    def testIndefModeChunked(self):
+        assert encoder.encode(
+            self.o, defMode=False, maxChunkSize=4
+        ) == ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110,
+                        32, 4, 3, 102,  111, 120, 0, 0))
+
+
+class ExpTaggedOctetStringEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.o = univ.OctetString().subtype(
+            value='Quick brown fox',
+            explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5)
+        )
+
+    def testDefMode(self):
+        assert encoder.encode(self.o) == ints2octs(
+            (101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.o, defMode=False
+        ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+
+    def testDefModeChunked(self):
+        assert encoder.encode(
+            self.o, defMode=True, maxChunkSize=4
+        ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3,
+                        102, 111, 120))
+
+    def testIndefModeChunked(self):
+        assert encoder.encode(
+            self.o, defMode=False, maxChunkSize=4
+        ) == ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))
+
+
+class NullEncoderTestCase(BaseTestCase):
+    def testNull(self):
+        assert encoder.encode(univ.Null('')) == ints2octs((5, 0))
+
+
+class ObjectIdentifierEncoderTestCase(BaseTestCase):
+    def testOne(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((1, 3, 6, 0, 0xffffe))
+        ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+
+    def testEdge1(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((0, 39))
+        ) == ints2octs((6, 1, 39))
+
+    def testEdge2(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((1, 39))
+        ) == ints2octs((6, 1, 79))
+
+    def testEdge3(self):
+        # 01111111
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 40))
+        ) == ints2octs((6, 1, 120))
+
+    def testEdge4(self):
+        # 10010000|10000000|10000000|10000000|01001111
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 0xffffffff))
+        ) == ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F))
+
+    def testEdge5(self):
+        # 01111111
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 47))
+        ) == ints2octs((6, 1, 0x7F))
+
+    def testEdge6(self):
+        # 10000001|00000000
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 48))
+        ) == ints2octs((6, 2, 0x81, 0x00))
+
+    def testEdge7(self):
+        # 10000001|00110100|00000003
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 100, 3))
+        ) == ints2octs((6, 3, 0x81, 0x34, 0x03))
+
+    def testEdge8(self):
+        # 10000101|00000000
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 560))
+        ) == ints2octs((6, 2, 133, 0))
+
+    def testEdge9(self):
+        # 10001000|10000100|10000111|0000010
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 16843570))
+        ) == ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02))
+
+    def testEdgeA(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 5))
+        ) == ints2octs((6, 1, 85))
+
+    def testImpossible1(self):
+        try:
+            encoder.encode(univ.ObjectIdentifier((3, 1, 2)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'impossible leading arc tolerated'
+
+    def testImpossible2(self):
+        try:
+            encoder.encode(univ.ObjectIdentifier((0,)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'single arc OID tolerated'
+
+    def testImpossible3(self):
+        try:
+            encoder.encode(univ.ObjectIdentifier((0, 40)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'second arc overflow tolerated'
+
+    def testImpossible4(self):
+        try:
+            encoder.encode(univ.ObjectIdentifier((1, 40)))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'second arc overflow tolerated'
+
+    def testLarge1(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 18446744073709551535184467440737095))
+        ) == ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB,
+                        0xE2, 0xB7, 0x17))
+
+    def testLarge2(self):
+        assert encoder.encode(
+            univ.ObjectIdentifier((2, 999, 18446744073709551535184467440737095))
+        ) == ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6,
+                        0xB8, 0xCB, 0xE2, 0xB6, 0x47))
+
+
+class RealEncoderTestCase(BaseTestCase):
+    def testChar(self):
+        assert encoder.encode(
+            univ.Real((123, 10, 11))
+        ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
+
+    def testBin1(self):
+        assert encoder.encode(  # default binEncBase = 2
+            univ.Real((0.5, 2, 0))  # check encbase = 2 and exponent = -1
+        ) == ints2octs((9, 3, 128, 255, 1))
+
+    def testBin2(self):
+        r = univ.Real((3.25, 2, 0))
+        r.binEncBase = 8  # change binEncBase only for this instance of Real
+        assert encoder.encode(
+            r  # check encbase = 8
+        ) == ints2octs((9, 3, 148, 255, 13))
+
+    def testBin3(self):
+        # change binEncBase in the RealEncoder instance => for all further Real
+        binEncBase, encoder.typeMap[univ.Real.typeId].binEncBase = encoder.typeMap[univ.Real.typeId].binEncBase, 16
+        assert encoder.encode(
+            univ.Real((0.00390625, 2, 0))  # check encbase = 16
+        ) == ints2octs((9, 3, 160, 254, 1))
+        encoder.typeMap[univ.Real.typeId].binEncBase = binEncBase
+
+    def testBin4(self):
+        # choose binEncBase automatically for all further Real (testBin[4-7])
+        binEncBase, encoder.typeMap[univ.Real.typeId].binEncBase = encoder.typeMap[univ.Real.typeId].binEncBase, None
+        assert encoder.encode(
+            univ.Real((1, 2, 0))  # check exponenta = 0
+        ) == ints2octs((9, 3, 128, 0, 1))
+        encoder.typeMap[univ.Real.typeId].binEncBase = binEncBase
+
+    def testBin5(self):
+        assert encoder.encode(
+            univ.Real((3, 2, -1020))  # case of 2 octs for exponent and
+            # negative exponenta and abs(exponent) is
+            # all 1's and fills the whole octet(s)
+        ) == ints2octs((9, 4, 129, 252, 4, 3))
+
+    def testBin6(self):
+        assert encoder.encode(
+            univ.Real((1, 2, 262140))  # case of 3 octs for exponent and
+            # check that first 9 bits for exponent
+            # are not all 1's
+        ) == ints2octs((9, 5, 130, 3, 255, 252, 1))
+
+    def testBin7(self):
+        assert encoder.encode(
+            univ.Real((-1, 2, 76354972))  # case of >3 octs for exponent and
+            # mantissa < 0
+        ) == ints2octs((9, 7, 195, 4, 4, 141, 21, 156, 1))
+
+    def testPlusInf(self):
+        assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64))
+
+    def testMinusInf(self):
+        assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65))
+
+    def testZero(self):
+        assert encoder.encode(univ.Real(0)) == ints2octs((9, 0))
+
+
+if sys.version_info[0:2] > (2, 5):
+    class UniversalStringEncoderTestCase(BaseTestCase):
+        def testEncoding(self):
+            assert encoder.encode(char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+                (28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99)), 'Incorrect encoding'
+
+
+class BMPStringEncoderTestCase(BaseTestCase):
+    def testEncoding(self):
+        assert encoder.encode(char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+            (30, 6, 0, 97, 0, 98, 0, 99)), 'Incorrect encoding'
+
+
+class UTF8StringEncoderTestCase(BaseTestCase):
+    def testEncoding(self):
+        assert encoder.encode(char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs(
+            (12, 3, 97, 98, 99)), 'Incorrect encoding'
+
+
+class SequenceOfEncoderTestCase(BaseTestCase):
+    def testEmpty(self):
+        s = univ.SequenceOf()
+        assert encoder.encode(s) == ints2octs((48, 0))
+
+    def testDefMode(self):
+        s = univ.SequenceOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(s) == ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testIndefMode(self):
+        s = univ.SequenceOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False
+        ) == ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testDefModeChunked(self):
+        s = univ.SequenceOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testIndefModeChunked(self):
+        s = univ.SequenceOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SequenceOfEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SequenceOf(componentType=univ.OctetString())
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, 'quick brown')
+
+    def testDefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((48, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+    def testEmpty(self):
+        s = univ.SetOf()
+        assert encoder.encode(s) == ints2octs((49, 0))
+
+    def testDefMode(self):
+        s = univ.SetOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(s) == ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testIndefMode(self):
+        s = univ.SetOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False
+        ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testDefModeChunked(self):
+        s = univ.SetOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testIndefModeChunked(self):
+        s = univ.SetOf()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SetOfEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SetOf(componentType=univ.OctetString())
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, 'quick brown')
+
+    def testDefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((49, 13, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 19, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        assert encoder.encode(self.s) == ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testDefModeChunked(self):
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+    def testIndefModeChunked(self):
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class SequenceEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null()),
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(1, 'quick brown')
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, '')
+        self.s.setComponentByPosition(2, 1)
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 5, 0, 0, 0))
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 2, 5, 0))
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 5, 0, 0, 0))
+
+    def testWithOptionalDefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(self.s) == ints2octs(
+            (48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testWithOptionalIndefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testWithOptionalDefModeChunked(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testWithOptionalIndefModeChunked(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs(
+            (48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+    def testWithDefaultedDefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1))
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+    def testWithDefaultedDefModeChunked(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((48, 5, 5, 0, 2, 1, 1))
+
+    def testWithDefaultedIndefModeChunked(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(self.s) == ints2octs(
+            (48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs(
+            (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0,
+                        0, 2, 1, 1, 0, 0))
+
+
+class ExpTaggedSequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('number', univ.Integer()),
+            )
+        )
+
+        s = s.subtype(
+            explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 5)
+        )
+
+        s[0] = 12
+
+        self.s = s
+
+    def testDefMode(self):
+        assert encoder.encode(self.s) == ints2octs((101, 5, 48, 3, 2, 1, 12))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((101, 128, 48, 128, 2, 1, 12, 0, 0, 0, 0))
+
+
+class ExpTaggedSequenceComponentEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('number', univ.Boolean().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+            )
+        )
+
+        self.s[0] = True
+
+    def testDefMode(self):
+        assert encoder.encode(self.s) == ints2octs((48, 5, 160, 3, 1, 1, 1))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((48, 128, 160, 3, 1, 1, 1, 0, 0, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        assert encoder.encode(self.s) == ints2octs((49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+    def testIndefMode(self):
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testDefModeChunked(self):
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+    def testIndefModeChunked(self):
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class SetEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null()),
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(1, 'quick brown')
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, '')
+        self.s.setComponentByPosition(2, 1)
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testDefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((49, 2, 5, 0))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 5, 0, 0, 0))
+
+    def testDefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 2, 5, 0))
+
+    def testIndefModeChunked(self):
+        self.__init()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 5, 0, 0, 0))
+
+    def testWithOptionalDefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(self.s) == ints2octs(
+            (49, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testWithOptionalIndefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testWithOptionalDefModeChunked(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testWithOptionalIndefModeChunked(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs(
+            (49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0))
+
+    def testWithDefaultedDefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(self.s) == ints2octs((49, 5, 5, 0, 2, 1, 1))
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0))
+
+    def testWithDefaultedDefModeChunked(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs((49, 5, 5, 0, 2, 1, 1))
+
+    def testWithDefaultedIndefModeChunked(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 5, 0, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedDefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(self.s) == ints2octs(
+            (49, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False
+        ) == ints2octs((49, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedDefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=True, maxChunkSize=4
+        ) == ints2octs(
+            (49, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1))
+
+    def testWithOptionalAndDefaultedIndefModeChunked(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s, defMode=False, maxChunkSize=4
+        ) == ints2octs((49, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0))
+
+
+class ChoiceEncoderTestCase(BaseTestCase):
+
+    def testEmpty(self):
+        s = univ.Choice()
+        try:
+            encoder.encode(s)
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'encoded unset choice'
+
+    def testDefModeOptionOne(self):
+        s = univ.Choice()
+        s.setComponentByPosition(0, univ.Null(''))
+        assert encoder.encode(s) == ints2octs((5, 0))
+
+    def testDefModeOptionTwo(self):
+        s = univ.Choice()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(s) == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testIndefMode(self):
+        s = univ.Choice()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False
+        ) == ints2octs((4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110))
+
+    def testDefModeChunked(self):
+        s = univ.Choice()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=True, maxChunkSize=4
+        ) == ints2octs((36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110))
+
+    def testIndefModeChunked(self):
+        s = univ.Choice()
+        s.setComponentByPosition(0, univ.OctetString('quick brown'))
+        assert encoder.encode(
+            s, defMode=False, maxChunkSize=4
+        ) == ints2octs((36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0))
+
+
+class ChoiceEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null('')),
+                namedtype.NamedType('number', univ.Integer(0)),
+                namedtype.NamedType('string', univ.OctetString())
+            )
+        )
+
+    def testEmpty(self):
+        try:
+            encoder.encode(self.s)
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'encoded unset choice'
+
+    def testFilled(self):
+        self.s.setComponentByPosition(0, univ.Null(''))
+        assert encoder.encode(self.s) == ints2octs((5, 0))
+
+    def testTagged(self):
+        s = self.s.subtype(
+            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)
+        )
+        s.setComponentByPosition(0, univ.Null(''))
+        assert encoder.encode(s) == ints2octs((164, 2, 5, 0))
+
+    def testUndefLength(self):
+        self.s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+        assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs(
+            (36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0))
+
+    def testTaggedUndefLength(self):
+        s = self.s.subtype(
+            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)
+        )
+        s.setComponentByPosition(2, univ.OctetString('abcdefgh'))
+        assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs(
+            (164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0))
+
+
+class AnyEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
+
+    def testUntagged(self):
+        assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120))
+
+    def testTaggedEx(self):
+        s = self.s.subtype(
+            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
+        )
+        assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120))
+
+    def testTaggedIm(self):
+        s = self.s.subtype(
+            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)
+        )
+        assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/cer/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.codec.cer.test_encoder.suite',
+     'tests.codec.cer.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/test_decoder.py
@@ -0,0 +1,71 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.codec.cer import decoder
+from pyasn1.compat.octets import ints2octs, str2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert decoder.decode(ints2octs((1, 1, 255))) == (1, null)
+
+    def testFalse(self):
+        assert decoder.decode(ints2octs((1, 1, 0))) == (0, null)
+
+    def testEmpty(self):
+        try:
+            decoder.decode(ints2octs((1, 0)))
+        except PyAsn1Error:
+            pass
+
+    def testOverflow(self):
+        try:
+            decoder.decode(ints2octs((1, 2, 0, 0)))
+        except PyAsn1Error:
+            pass
+
+class BitStringDecoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert decoder.decode(
+            ints2octs((3, 3, 6, 170, 128))
+        ) == (((1, 0) * 5), null)
+
+    def testLongMode(self):
+        assert decoder.decode(
+            ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+        ) == (((1, 0) * 501), null)
+
+    # TODO: test failures on short chunked and long unchunked substrate samples
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert decoder.decode(
+            ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)),
+        ) == (str2octs('Quick brown fox'), null)
+
+    def testLongMode(self):
+        assert decoder.decode(
+            ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0))
+        ) == (str2octs('Q' * 1001), null)
+
+    # TODO: test failures on short chunked and long unchunked substrate samples
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/cer/test_encoder.py
@@ -0,0 +1,677 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ, useful
+from pyasn1.codec.cer import encoder
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255))
+
+    def testFalse(self):
+        assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0))
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert encoder.encode(
+            univ.BitString((1, 0) * 5)
+        ) == ints2octs((3, 3, 6, 170, 128))
+
+    def testLongMode(self):
+        assert encoder.encode(univ.BitString((1, 0) * 501)) == ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert encoder.encode(
+            univ.OctetString('Quick brown fox')
+        ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+    def testLongMode(self):
+        assert encoder.encode(
+            univ.OctetString('Q' * 1001)
+        ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0))
+
+
+class GeneralizedTimeEncoderTestCase(BaseTestCase):
+    #    def testExtraZeroInSeconds(self):
+    #        try:
+    #            assert encoder.encode(
+    #                useful.GeneralizedTime('20150501120112.10Z')
+    #            )
+    #        except PyAsn1Error:
+    #            pass
+    #        else:
+    #            assert 0, 'Meaningless trailing zero in fraction part tolerated'
+
+    def testLocalTimezone(self):
+        try:
+            assert encoder.encode(
+                useful.GeneralizedTime('20150501120112.1+0200')
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Local timezone tolerated'
+
+    def testMissingTimezone(self):
+        try:
+            assert encoder.encode(
+                useful.GeneralizedTime('20150501120112.1')
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Missing timezone tolerated'
+
+
+    def testDecimalCommaPoint(self):
+        try:
+            assert encoder.encode(
+                    useful.GeneralizedTime('20150501120112,1Z')
+             )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Decimal comma tolerated'
+
+    def testWithSubseconds(self):
+        assert encoder.encode(
+                    useful.GeneralizedTime('20170801120112.59Z')
+             ) == ints2octs((24, 18, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 46, 53, 57, 90))
+
+    def testWithSeconds(self):
+        assert encoder.encode(
+                    useful.GeneralizedTime('20170801120112Z')
+             ) == ints2octs((24, 15, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+
+    def testWithMinutes(self):
+        assert encoder.encode(
+                    useful.GeneralizedTime('201708011201Z')
+             ) == ints2octs((24, 13, 50, 48, 49, 55, 48, 56, 48, 49, 49, 50, 48, 49, 90))
+
+
+class UTCTimeEncoderTestCase(BaseTestCase):
+    def testFractionOfSecond(self):
+        try:
+            assert encoder.encode(
+                useful.UTCTime('150501120112.10Z')
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Decimal point tolerated'
+
+    def testMissingTimezone(self):
+        try:
+            assert encoder.encode(
+                useful.UTCTime('150501120112')
+            ) == ints2octs((23, 13, 49, 53, 48, 53, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Missing timezone tolerated'
+
+    def testLocalTimezone(self):
+        try:
+            assert encoder.encode(
+                useful.UTCTime('150501120112+0200')
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Local timezone tolerated'
+
+    def testWithSeconds(self):
+        assert encoder.encode(
+                    useful.UTCTime('990801120112Z')
+             ) == ints2octs((23, 13, 57, 57, 48, 56, 48, 49, 49, 50, 48, 49, 49, 50, 90))
+
+    def testWithMinutes(self):
+        assert encoder.encode(
+                    useful.UTCTime('9908011201Z')
+             ) == ints2octs((23, 11, 57, 57, 48, 56, 48, 49, 49, 50, 48, 49, 90))
+
+
+class SequenceOfEncoderTestCase(BaseTestCase):
+    def testEmpty(self):
+        s = univ.SequenceOf()
+        assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+    def testDefMode1(self):
+        s = univ.SequenceOf()
+        s.append(univ.OctetString('a'))
+        s.append(univ.OctetString('ab'))
+        assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testDefMode2(self):
+        s = univ.SequenceOf()
+        s.append(univ.OctetString('ab'))
+        s.append(univ.OctetString('a'))
+        assert encoder.encode(s) == ints2octs((48, 128, 4, 2, 97, 98, 4, 1, 97, 0, 0))
+
+    def testDefMode3(self):
+        s = univ.SequenceOf()
+        s.append(univ.OctetString('b'))
+        s.append(univ.OctetString('a'))
+        assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 98, 4, 1, 97, 0, 0))
+
+    def testDefMode4(self):
+        s = univ.SequenceOf()
+        s.append(univ.OctetString('a'))
+        s.append(univ.OctetString('b'))
+        assert encoder.encode(s) == ints2octs((48, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SequenceOfEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SequenceOf(componentType=univ.OctetString())
+
+    def testEmpty(self):
+        self.s.clear()
+        assert encoder.encode(self.s) == ints2octs((48, 128, 0, 0))
+
+    def testIndefMode1(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('ab')
+        assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testIndefMode2(self):
+        self.s.clear()
+        self.s.append('ab')
+        self.s.append('a')
+        assert encoder.encode(self.s) == ints2octs((48, 128, 4, 2, 97, 98, 4, 1, 97, 0, 0))
+
+    def testIndefMode3(self):
+        self.s.clear()
+        self.s.append('b')
+        self.s.append('a')
+        assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 98, 4, 1, 97, 0, 0))
+
+    def testIndefMode4(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('b')
+        assert encoder.encode(self.s) == ints2octs((48, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+    def testEmpty(self):
+        s = univ.SetOf()
+        assert encoder.encode(s) == ints2octs((49, 128, 0, 0))
+
+    def testDefMode1(self):
+        s = univ.SetOf()
+        s.append(univ.OctetString('a'))
+        s.append(univ.OctetString('ab'))
+        assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testDefMode2(self):
+        s = univ.SetOf()
+        s.append(univ.OctetString('ab'))
+        s.append(univ.OctetString('a'))
+        assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testDefMode3(self):
+        s = univ.SetOf()
+        s.append(univ.OctetString('b'))
+        s.append(univ.OctetString('a'))
+        assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+    def testDefMode4(self):
+        s = univ.SetOf()
+        s.append(univ.OctetString('a'))
+        s.append(univ.OctetString('b'))
+        assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetOfEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.SetOf(componentType=univ.OctetString())
+
+    def testEmpty(self):
+        self.s.clear()
+        assert encoder.encode(self.s) == ints2octs((49, 128, 0, 0))
+
+    def testIndefMode1(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('ab')
+
+        assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testIndefMode2(self):
+        self.s.clear()
+        self.s.append('ab')
+        self.s.append('a')
+
+        assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 2, 97, 98, 0, 0))
+
+    def testIndefMode3(self):
+        self.s.clear()
+        self.s.append('b')
+        self.s.append('a')
+
+        assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+    def testIndefMode4(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('b')
+
+        assert encoder.encode(self.s) == ints2octs((49, 128, 4, 1, 97, 4, 1, 98, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testIndefMode(self):
+        assert encoder.encode(self.s) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithOptionalIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SetEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('place-holder', univ.Null('')),
+            namedtype.OptionalNamedType('first-name', univ.OctetString()),
+            namedtype.DefaultedNamedType('age', univ.Integer(33))
+        ))
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(1, 'quick brown')
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(2, 1)
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0))
+
+    def testWithOptionalIndefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SetWithChoiceWithSchemaEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        c = univ.Choice(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('actual', univ.Boolean(0))
+        ))
+        self.s = univ.Set(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('place-holder', univ.Null('')),
+            namedtype.NamedType('status', c)
+        ))
+
+    def testIndefMode(self):
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByName('status')
+        self.s.getComponentByName('status').setComponentByPosition(0, 1)
+        assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0))
+
+
+class SetEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Set()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testIndefMode(self):
+        assert encoder.encode(self.s) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithOptionalIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0))
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testIndefMode(self):
+        assert encoder.encode(self.s) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testWithOptionalIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testWithDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+
+class SequenceEncoderWithSchemaTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null('')),
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33))
+            )
+        )
+
+    def __init(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+
+    def __initWithOptional(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(1, 'quick brown')
+
+    def __initWithDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0)
+        self.s.setComponentByPosition(2, 1)
+
+    def __initWithOptionalAndDefaulted(self):
+        self.s.clear()
+        self.s.setComponentByPosition(0, univ.Null(''))
+        self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+        self.s.setComponentByPosition(2, univ.Integer(1))
+
+    def testIndefMode(self):
+        self.__init()
+        assert encoder.encode(self.s) == ints2octs((48, 128, 5, 0, 0, 0))
+
+    def testWithOptionalIndefMode(self):
+        self.__initWithOptional()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0))
+
+    def testWithDefaultedIndefMode(self):
+        self.__initWithDefaulted()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0))
+
+    def testWithOptionalAndDefaultedIndefMode(self):
+        self.__initWithOptionalAndDefaulted()
+        assert encoder.encode(
+            self.s
+        ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0))
+
+
+class NestedOptionalSequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        inner = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+        outerWithOptional = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', inner),
+            )
+        )
+
+        outerWithDefault = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.DefaultedNamedType('inner', inner),
+            )
+        )
+
+        self.s1 = outerWithOptional
+        self.s2 = outerWithDefault
+
+    def __initOptionalWithDefaultAndOptional(self):
+        self.s1.clear()
+        self.s1[0][0] = 'test'
+        self.s1[0][1] = 123
+        return self.s1
+
+    def __initOptionalWithDefault(self):
+        self.s1.clear()
+        self.s1[0][1] = 123
+        return self.s1
+
+    def __initOptionalWithOptional(self):
+        self.s1.clear()
+        self.s1[0][0] = 'test'
+        return self.s1
+
+    def __initOptional(self):
+        self.s1.clear()
+        return self.s1
+
+    def __initDefaultWithDefaultAndOptional(self):
+        self.s2.clear()
+        self.s2[0][0] = 'test'
+        self.s2[0][1] = 123
+        return self.s2
+
+    def __initDefaultWithDefault(self):
+        self.s2.clear()
+        self.s2[0][0] = 'test'
+        return self.s2
+
+    def __initDefaultWithOptional(self):
+        self.s2.clear()
+        self.s2[0][1] = 123
+        return self.s2
+
+    def testOptionalWithDefaultAndOptional(self):
+        s = self.__initOptionalWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+    def testOptionalWithDefault(self):
+        s = self.__initOptionalWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+    def testOptionalWithOptional(self):
+        s = self.__initOptionalWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+    def testOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+    def testDefaultWithDefaultAndOptional(self):
+        s = self.__initDefaultWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+    def testDefaultWithDefault(self):
+        s = self.__initDefaultWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+    def testDefaultWithOptional(self):
+        s = self.__initDefaultWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+
+class NestedOptionalChoiceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        layer3 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+        layer2 = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('inner', layer3),
+                namedtype.NamedType('first-name', univ.OctetString())
+            )
+        )
+
+        layer1 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', layer2),
+            )
+        )
+
+        self.s = layer1
+
+    def __initOptionalWithDefaultAndOptional(self):
+        self.s.clear()
+        self.s[0][0][0] = 'test'
+        self.s[0][0][1] = 123
+        return self.s
+
+    def __initOptionalWithDefault(self):
+        self.s.clear()
+        self.s[0][0][1] = 123
+        return self.s
+
+    def __initOptionalWithOptional(self):
+        self.s.clear()
+        self.s[0][0][0] = 'test'
+        return self.s
+
+    def __initOptional(self):
+        self.s.clear()
+        return self.s
+
+    def testOptionalWithDefaultAndOptional(self):
+        s = self.__initOptionalWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 2, 1, 123, 0, 0, 0, 0))
+
+    def testOptionalWithDefault(self):
+        s = self.__initOptionalWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 2, 1, 123, 0, 0, 0, 0))
+
+    def testOptionalWithOptional(self):
+        s = self.__initOptionalWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+    def testOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+
+class NestedOptionalSequenceOfEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        layer2 = univ.SequenceOf(
+            componentType=univ.OctetString()
+        )
+
+        layer1 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', layer2),
+            )
+        )
+
+        self.s = layer1
+
+    def __initOptionalWithValue(self):
+        self.s.clear()
+        self.s[0][0] = 'test'
+        return self.s
+
+    def __initOptional(self):
+        self.s.clear()
+        return self.s
+
+    def testOptionalWithValue(self):
+        s = self.__initOptionalWithValue()
+        assert encoder.encode(s) == ints2octs((48, 128, 48, 128, 4, 4, 116, 101, 115, 116, 0, 0, 0, 0))
+
+    def testOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 128, 0, 0))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/der/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/__main__.py
@@ -0,0 +1,20 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.codec.der.test_encoder.suite',
+     'tests.codec.der.test_decoder.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/test_decoder.py
@@ -0,0 +1,78 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.codec.der import decoder
+from pyasn1.compat.octets import ints2octs, null
+from pyasn1.error import PyAsn1Error
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert decoder.decode(
+            ints2octs((3, 127, 6) + (170,) * 125 + (128,))
+        ) == (((1, 0) * 501), null)
+
+    def testIndefMode(self):
+        try:
+            decoder.decode(
+                ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'indefinite length encoding tolerated'
+
+    def testDefModeChunked(self):
+        try:
+            assert decoder.decode(
+                ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'chunked encoding tolerated'
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+    def testShortMode(self):
+        assert decoder.decode(
+            '\004\017Quick brown fox'.encode()
+        ) == ('Quick brown fox'.encode(), ''.encode())
+
+    def testIndefMode(self):
+        try:
+            decoder.decode(
+                ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'indefinite length encoding tolerated'
+
+    def testChunkedMode(self):
+        try:
+            decoder.decode(
+                ints2octs((36, 23, 4, 2, 81, 117, 4, 2, 105, 99, 4, 2, 107, 32, 4, 2, 98, 114, 4, 2, 111, 119, 4, 1, 110))
+            )
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'chunked encoding tolerated'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/der/test_encoder.py
@@ -0,0 +1,295 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.der import encoder
+from pyasn1.compat.octets import ints2octs
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+    def testDefModeShort(self):
+        assert encoder.encode(
+            univ.OctetString('Quick brown fox')
+        ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120))
+
+    def testDefModeLong(self):
+        assert encoder.encode(
+            univ.OctetString('Q' * 10000)
+        ) == ints2octs((4, 130, 39, 16) + (81,) * 10000)
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+    def testDefModeShort(self):
+        assert encoder.encode(
+            univ.BitString((1,))
+        ) == ints2octs((3, 2, 7, 128))
+
+    def testDefModeLong(self):
+        assert encoder.encode(
+            univ.BitString((1,) * 80000)
+        ) == ints2octs((3, 130, 39, 17, 0) + (255,) * 10000)
+
+
+class SetOfEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.SetOf(componentType=univ.OctetString())
+
+    def testDefMode1(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('ab')
+
+        assert encoder.encode(self.s) == ints2octs((49, 7, 4, 1, 97, 4, 2, 97, 98))
+
+    def testDefMode2(self):
+        self.s.clear()
+        self.s.append('ab')
+        self.s.append('a')
+
+        assert encoder.encode(self.s) == ints2octs((49, 7, 4, 1, 97, 4, 2, 97, 98))
+
+    def testDefMode3(self):
+        self.s.clear()
+        self.s.append('b')
+        self.s.append('a')
+
+        assert encoder.encode(self.s) == ints2octs((49, 6, 4, 1, 97, 4, 1, 98))
+
+    def testDefMode4(self):
+        self.s.clear()
+        self.s.append('a')
+        self.s.append('b')
+
+        assert encoder.encode(self.s) == ints2octs((49, 6, 4, 1, 97, 4, 1, 98))
+
+class SetWithChoiceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        c = univ.Choice(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('name', univ.OctetString()),
+            namedtype.NamedType('amount', univ.Boolean()))
+        )
+
+        self.s = univ.Set(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('value', univ.Integer(5)),
+            namedtype.NamedType('status', c))
+        )
+
+    def testComponentsOrdering1(self):
+        self.s.setComponentByName('status')
+        self.s.getComponentByName('status').setComponentByPosition(0, 'A')
+        assert encoder.encode(self.s) == ints2octs((49, 6, 2, 1, 5, 4, 1, 65))
+
+    def testComponentsOrdering2(self):
+        self.s.setComponentByName('status')
+        self.s.getComponentByName('status').setComponentByPosition(1, True)
+        assert encoder.encode(self.s) == ints2octs((49, 6, 1, 1, 255, 2, 1, 5))
+
+
+class NestedOptionalSequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        inner = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+        outerWithOptional = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', inner),
+            )
+        )
+
+        outerWithDefault = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.DefaultedNamedType('inner', inner),
+            )
+        )
+
+        self.s1 = outerWithOptional
+        self.s2 = outerWithDefault
+
+    def __initOptionalWithDefaultAndOptional(self):
+        self.s1.clear()
+        self.s1[0][0] = 'test'
+        self.s1[0][1] = 123
+        return self.s1
+
+    def __initOptionalWithDefault(self):
+        self.s1.clear()
+        self.s1[0][1] = 123
+        return self.s1
+
+    def __initOptionalWithOptional(self):
+        self.s1.clear()
+        self.s1[0][0] = 'test'
+        return self.s1
+
+    def __initOptional(self):
+        self.s1.clear()
+        return self.s1
+
+    def __initDefaultWithDefaultAndOptional(self):
+        self.s2.clear()
+        self.s2[0][0] = 'test'
+        self.s2[0][1] = 123
+        return self.s2
+
+    def __initDefaultWithDefault(self):
+        self.s2.clear()
+        self.s2[0][0] = 'test'
+        return self.s2
+
+    def __initDefaultWithOptional(self):
+        self.s2.clear()
+        self.s2[0][1] = 123
+        return self.s2
+
+    def testDefModeOptionalWithDefaultAndOptional(self):
+        s = self.__initOptionalWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+    def testDefModeOptionalWithDefault(self):
+        s = self.__initOptionalWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+    def testDefModeOptionalWithOptional(self):
+        s = self.__initOptionalWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+    def testDefModeOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 0))
+
+    def testDefModeDefaultWithDefaultAndOptional(self):
+        s = self.__initDefaultWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+    def testDefModeDefaultWithDefault(self):
+        s = self.__initDefaultWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+    def testDefModeDefaultWithOptional(self):
+        s = self.__initDefaultWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+
+class NestedOptionalChoiceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        layer3 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('first-name', univ.OctetString()),
+                namedtype.DefaultedNamedType('age', univ.Integer(33)),
+            )
+        )
+
+        layer2 = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('inner', layer3),
+                namedtype.NamedType('first-name', univ.OctetString())
+            )
+        )
+
+        layer1 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', layer2),
+            )
+        )
+
+        self.s = layer1
+
+    def __initOptionalWithDefaultAndOptional(self):
+        self.s.clear()
+        self.s[0][0][0] = 'test'
+        self.s[0][0][1] = 123
+        return self.s
+
+    def __initOptionalWithDefault(self):
+        self.s.clear()
+        self.s[0][0][1] = 123
+        return self.s
+
+    def __initOptionalWithOptional(self):
+        self.s.clear()
+        self.s[0][0][0] = 'test'
+        return self.s
+
+    def __initOptional(self):
+        self.s.clear()
+        return self.s
+
+    def testDefModeOptionalWithDefaultAndOptional(self):
+        s = self.__initOptionalWithDefaultAndOptional()
+        assert encoder.encode(s) == ints2octs((48, 11, 48, 9, 4, 4, 116, 101, 115, 116, 2, 1, 123))
+
+    def testDefModeOptionalWithDefault(self):
+        s = self.__initOptionalWithDefault()
+        assert encoder.encode(s) == ints2octs((48, 5, 48, 3, 2, 1, 123))
+
+    def testDefModeOptionalWithOptional(self):
+        s = self.__initOptionalWithOptional()
+        assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+    def testDefModeOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 0))
+
+
+class NestedOptionalSequenceOfEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        layer2 = univ.SequenceOf(
+            componentType=univ.OctetString()
+        )
+
+        layer1 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.OptionalNamedType('inner', layer2),
+            )
+        )
+
+        self.s = layer1
+
+    def __initOptionalWithValue(self):
+        self.s.clear()
+        self.s[0][0] = 'test'
+        return self.s
+
+    def __initOptional(self):
+        self.s.clear()
+        return self.s
+
+    def testDefModeOptionalWithValue(self):
+        s = self.__initOptionalWithValue()
+        assert encoder.encode(s) == ints2octs((48, 8, 48, 6, 4, 4, 116, 101, 115, 116))
+
+    def testDefModeOptional(self):
+        s = self.__initOptional()
+        assert encoder.encode(s) == ints2octs((48, 0))
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/codec/native/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/__main__.py
@@ -0,0 +1,19 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.codec.native.test_encoder.suite',
+     'tests.codec.native.test_decoder.suite']
+)
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/test_decoder.py
@@ -0,0 +1,123 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.native import decoder
+from pyasn1.error import PyAsn1Error
+
+
+class BadAsn1SpecTestCase(BaseTestCase):
+    def testBadSpec(self):
+        try:
+            decoder.decode('', asn1Spec='not an Asn1Item')
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Invalid asn1Spec accepted'
+
+
+class IntegerDecoderTestCase(BaseTestCase):
+    def testPosInt(self):
+        assert decoder.decode(12, asn1Spec=univ.Integer()) == univ.Integer(12)
+
+    def testNegInt(self):
+        assert decoder.decode(-12, asn1Spec=univ.Integer()) == univ.Integer(-12)
+
+
+class BooleanDecoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert decoder.decode(True, asn1Spec=univ.Boolean()) == univ.Boolean(True)
+
+    def testTrueNeg(self):
+        assert decoder.decode(False, asn1Spec=univ.Boolean()) == univ.Boolean(False)
+
+
+class BitStringDecoderTestCase(BaseTestCase):
+    def testSimple(self):
+        assert decoder.decode('11111111', asn1Spec=univ.BitString()) == univ.BitString(hexValue='ff')
+
+
+class OctetStringDecoderTestCase(BaseTestCase):
+    def testSimple(self):
+        assert decoder.decode('Quick brown fox', asn1Spec=univ.OctetString()) == univ.OctetString('Quick brown fox')
+
+
+class NullDecoderTestCase(BaseTestCase):
+    def testNull(self):
+        assert decoder.decode(None, asn1Spec=univ.Null()) == univ.Null()
+
+
+class ObjectIdentifierDecoderTestCase(BaseTestCase):
+    def testOne(self):
+        assert decoder.decode('1.3.6.11', asn1Spec=univ.ObjectIdentifier()) == univ.ObjectIdentifier('1.3.6.11')
+
+
+class RealDecoderTestCase(BaseTestCase):
+    def testSimple(self):
+        assert decoder.decode(1.33, asn1Spec=univ.Real()) == univ.Real(1.33)
+
+
+class SequenceDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null()),
+                namedtype.NamedType('first-name', univ.OctetString()),
+                namedtype.NamedType('age', univ.Integer(33))
+            )
+        )
+
+    def testSimple(self):
+        s = self.s.clone()
+        s[0] = univ.Null()
+        s[1] = univ.OctetString('xx')
+        s[2] = univ.Integer(33)
+        assert decoder.decode({'place-holder': None, 'first-name': 'xx', 'age': 33}, asn1Spec=self.s) == s
+
+
+class ChoiceDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null()),
+                namedtype.NamedType('first-name', univ.OctetString()),
+                namedtype.NamedType('age', univ.Integer(33))
+            )
+        )
+
+    def testSimple(self):
+        s = self.s.clone()
+        s[1] = univ.OctetString('xx')
+        assert decoder.decode({'first-name': 'xx'}, asn1Spec=self.s) == s
+
+
+class AnyDecoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.Any()
+
+    def testSimple(self):
+        assert decoder.decode('fox', asn1Spec=univ.Any()) == univ.Any('fox')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/codec/native/test_encoder.py
@@ -0,0 +1,144 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.codec.native import encoder
+from pyasn1.compat.octets import str2octs
+from pyasn1.error import PyAsn1Error
+
+
+class BadAsn1SpecTestCase(BaseTestCase):
+    def testBadValueType(self):
+        try:
+            encoder.encode('not an Asn1Item')
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert 0, 'Invalid value type accepted'
+
+
+class IntegerEncoderTestCase(BaseTestCase):
+    def testPosInt(self):
+        assert encoder.encode(univ.Integer(12)) == 12
+
+    def testNegInt(self):
+        assert encoder.encode(univ.Integer(-12)) == -12
+
+
+class BooleanEncoderTestCase(BaseTestCase):
+    def testTrue(self):
+        assert encoder.encode(univ.Boolean(1)) is True
+
+    def testFalse(self):
+        assert encoder.encode(univ.Boolean(0)) is False
+
+
+class BitStringEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1))
+
+    def testValue(self):
+        assert encoder.encode(self.b) == '101010011000101'
+
+
+class OctetStringEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.o = univ.OctetString('Quick brown fox')
+
+    def testValue(self):
+        assert encoder.encode(self.o) == str2octs('Quick brown fox')
+
+
+class NullEncoderTestCase(BaseTestCase):
+    def testNull(self):
+        assert encoder.encode(univ.Null('')) is None
+
+
+class ObjectIdentifierEncoderTestCase(BaseTestCase):
+    def testOne(self):
+        assert encoder.encode(univ.ObjectIdentifier((1, 3, 6, 0, 12345))) == '1.3.6.0.12345'
+
+
+class RealEncoderTestCase(BaseTestCase):
+    def testChar(self):
+        assert encoder.encode(univ.Real((123, 10, 11))) == 1.23e+13
+
+    def testPlusInf(self):
+        assert encoder.encode(univ.Real('inf')) == float('inf')
+
+    def testMinusInf(self):
+        assert encoder.encode(univ.Real('-inf')) == float('-inf')
+
+
+class SequenceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.Sequence(componentType=namedtype.NamedTypes(
+            namedtype.NamedType('place-holder', univ.Null('')),
+            namedtype.OptionalNamedType('first-name', univ.OctetString('')),
+            namedtype.DefaultedNamedType('age', univ.Integer(33)),
+        ))
+
+    def testSimple(self):
+        s = self.s.clone()
+        s[0] = univ.Null('')
+        s[1] = 'abc'
+        s[2] = 123
+        assert encoder.encode(s) == {'place-holder': None, 'first-name': str2octs('abc'), 'age': 123}
+
+
+class ChoiceEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('place-holder', univ.Null('')),
+                namedtype.NamedType('number', univ.Integer(0)),
+                namedtype.NamedType('string', univ.OctetString())
+           )
+        )
+
+    def testEmpty(self):
+        try:
+            encoder.encode(self.s)
+        except PyAsn1Error:
+            pass
+        else:
+            assert False, 'encoded unset choice'
+
+    def testFilled(self):
+        self.s.setComponentByPosition(0, univ.Null(''))
+        assert encoder.encode(self.s) == {'place-holder': None}
+
+
+class AnyEncoderTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s = univ.Any(encoder.encode(univ.OctetString('fox')))
+
+    def testSimple(self):
+        assert encoder.encode(self.s) == str2octs('fox')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/compat/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/__main__.py
@@ -0,0 +1,21 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.compat.test_binary.suite',
+     'tests.compat.test_integer.suite',
+     'tests.compat.test_octets.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_binary.py
@@ -0,0 +1,56 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import binary
+
+
+class BinaryTestCase(BaseTestCase):
+
+    def test_bin_zero(self):
+        assert '0b0' == binary.bin(0)
+
+
+    def test_bin_noarg(self):
+        try:
+            binary.bin()
+
+        except TypeError:
+            pass
+
+        except:
+            assert 0, 'bin() tolerates no arguments'
+
+
+    def test_bin_allones(self):
+        assert '0b1111111111111111111111111111111111111111111111111111111111111111' == binary.bin(0xffffffffffffffff)
+
+
+    def test_bin_allzeros(self):
+        assert '0b0' == binary.bin(0x0000000)
+
+
+
+    def test_bin_pos(self):
+        assert '0b1000000010000000100000001' == binary.bin(0x01010101)
+
+
+    def test_bin_neg(self):
+        assert '-0b1000000010000000100000001' == binary.bin(-0x01010101)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_integer.py
@@ -0,0 +1,53 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import integer
+
+
+class IntegerTestCase(BaseTestCase):
+
+    if sys.version_info[0] > 2:
+
+        def test_from_bytes_zero(self):
+            assert 0 == integer.from_bytes(bytes([0]), signed=False)
+
+        def test_from_bytes_unsigned(self):
+            assert -66051 == integer.from_bytes(bytes([254, 253, 253]), signed=True)
+
+        def test_from_bytes_signed(self):
+            assert 66051 == integer.from_bytes(bytes([0, 1, 2, 3]), signed=False)
+
+        def test_from_bytes_empty(self):
+            assert 0 == integer.from_bytes(bytes([]))
+
+    else:
+
+        def test_from_bytes_zero(self):
+            assert 0 == integer.from_bytes('\x00', signed=False)
+
+        def test_from_bytes_unsigned(self):
+            assert -66051 == integer.from_bytes('\xfe\xfd\xfd', signed=True)
+
+        def test_from_bytes_signed(self):
+            assert 66051 == integer.from_bytes('\x01\x02\x03', signed=False)
+
+        def test_from_bytes_empty(self):
+            assert 0 == integer.from_bytes('')
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/compat/test_octets.py
@@ -0,0 +1,117 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.compat import octets
+
+
+class OctetsTestCase(BaseTestCase):
+
+    if sys.version_info[0] > 2:
+
+        def test_ints2octs(self):
+            assert [1, 2, 3] == list(octets.ints2octs([1, 2, 3]))
+
+        def test_ints2octs_empty(self):
+            assert not octets.ints2octs([])
+
+        def test_int2oct(self):
+            assert [12] == list(octets.int2oct(12))
+
+        def test_octs2ints(self):
+            assert [1, 2, 3] == list(octets.octs2ints(bytes([1, 2, 3])))
+
+        def test_octs2ints_empty(self):
+            assert not octets.octs2ints(bytes([]))
+
+        def test_oct2int(self):
+            assert 12 == octets.oct2int(bytes([12]))[0]
+
+        def test_str2octs(self):
+            assert bytes([1, 2, 3]) == octets.str2octs('\x01\x02\x03')
+
+        def test_str2octs_empty(self):
+            assert not octets.str2octs('')
+
+        def test_octs2str(self):
+            assert '\x01\x02\x03' == octets.octs2str(bytes([1, 2, 3]))
+
+        def test_octs2str_empty(self):
+            assert not octets.octs2str(bytes([]))
+
+        def test_isOctetsType(self):
+            assert octets.isOctetsType('abc') == False
+            assert octets.isOctetsType(123) == False
+            assert octets.isOctetsType(bytes()) == True
+
+        def test_isStringType(self):
+            assert octets.isStringType('abc') == True
+            assert octets.isStringType(123) == False
+            assert octets.isStringType(bytes()) == False
+
+        def test_ensureString(self):
+            assert 'abc'.encode() == octets.ensureString('abc'.encode())
+            assert bytes([1, 2, 3]) == octets.ensureString([1, 2, 3])
+
+    else:
+
+        def test_ints2octs(self):
+            assert '\x01\x02\x03' == octets.ints2octs([1, 2, 3])
+
+        def test_ints2octs_empty(self):
+            assert not octets.ints2octs([])
+
+        def test_int2oct(self):
+            assert '\x0c' == octets.int2oct(12)
+
+        def test_octs2ints(self):
+            assert [1, 2, 3] == octets.octs2ints('\x01\x02\x03')
+
+        def test_octs2ints_empty(self):
+            assert not octets.octs2ints('')
+
+        def test_oct2int(self):
+            assert 12 == octets.oct2int('\x0c')
+
+        def test_str2octs(self):
+            assert '\x01\x02\x03' == octets.str2octs('\x01\x02\x03')
+
+        def test_str2octs_empty(self):
+            assert not octets.str2octs('')
+
+        def test_octs2str(self):
+            assert '\x01\x02\x03' == octets.octs2str('\x01\x02\x03')
+
+        def test_octs2str_empty(self):
+            assert not octets.octs2str('')
+
+        def test_isOctetsType(self):
+            assert octets.isOctetsType('abc') == True
+            assert octets.isOctetsType(123) == False
+            assert octets.isOctetsType(unicode('abc')) == False
+
+        def test_isStringType(self):
+            assert octets.isStringType('abc') == True
+            assert octets.isStringType(123) == False
+            assert octets.isStringType(unicode('abc')) == True
+
+        def test_ensureString(self):
+            assert 'abc' == octets.ensureString('abc')
+            assert '123' == octets.ensureString(123)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/test_debug.py
@@ -0,0 +1,42 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1 import debug
+from pyasn1 import error
+
+class DebugCaseBase(BaseTestCase):
+    def testKnownFlags(self):
+        debug.setLogger(0)
+        debug.setLogger(debug.Debug('all', 'encoder', 'decoder'))
+        debug.setLogger(0)
+
+    def testUnknownFlags(self):
+        try:
+            debug.setLogger(debug.Debug('all', 'unknown', loggerName='xxx'))
+
+        except error.PyAsn1Error:
+            debug.setLogger(0)
+            return
+
+        else:
+            debug.setLogger(0)
+            assert 0, 'unknown debug flag tolerated'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
copy from third_party/python/pyasn1/test/__init__.py
copy to third_party/python/pyasn1/tests/type/__init__.py
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/__main__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+suite = unittest.TestLoader().loadTestsFromNames(
+    ['tests.type.test_constraint.suite',
+     'tests.type.test_namedtype.suite',
+     'tests.type.test_namedval.suite',
+     'tests.type.test_tag.suite',
+     'tests.type.test_univ.suite',
+     'tests.type.test_char.suite',
+     'tests.type.test_useful.suite']
+)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_char.py
@@ -0,0 +1,156 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import char, univ, constraint
+from pyasn1.compat.octets import ints2octs
+from pyasn1.error import PyAsn1Error
+
+
+class AbstractStringTestCase(object):
+
+    initializer = ()
+    encoding = 'us-ascii'
+    asn1Type = None
+
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.asn1String = self.asn1Type(ints2octs(self.initializer), encoding=self.encoding)
+        self.pythonString = ints2octs(self.initializer).decode(self.encoding)
+
+    def testUnicode(self):
+        assert self.asn1String == self.pythonString, 'unicode init fails'
+
+    def testLength(self):
+        assert len(self.asn1String) == len(self.pythonString), 'unicode len() fails'
+
+    def testSizeConstraint(self):
+        asn1Spec = self.asn1Type(subtypeSpec=constraint.ValueSizeConstraint(1, 1))
+
+        try:
+            asn1Spec.clone(self.pythonString)
+        except PyAsn1Error:
+            pass
+        else:
+            assert False, 'Size constraint tolerated'
+
+        try:
+            asn1Spec.clone(self.pythonString[0])
+        except PyAsn1Error:
+            assert False, 'Size constraint failed'
+
+    def testSerialized(self):
+        if sys.version_info[0] < 3:
+            assert str(self.asn1String) == self.pythonString.encode(self.encoding), '__str__() fails'
+        else:
+            assert bytes(self.asn1String) == self.pythonString.encode(self.encoding), '__str__() fails'
+
+    def testPrintable(self):
+        if sys.version_info[0] < 3:
+            assert unicode(self.asn1String) == self.pythonString, '__str__() fails'
+        else:
+            assert str(self.asn1String) == self.pythonString, '__str__() fails'
+
+    def testInit(self):
+        assert self.asn1Type(self.pythonString) == self.pythonString
+        assert self.asn1Type(self.pythonString.encode(self.encoding)) == self.pythonString
+        assert self.asn1Type(univ.OctetString(self.pythonString.encode(self.encoding))) == self.pythonString
+        assert self.asn1Type(self.asn1Type(self.pythonString)) == self.pythonString
+        assert self.asn1Type(self.initializer, encoding=self.encoding) == self.pythonString
+
+    def testInitFromAsn1(self):
+        assert self.asn1Type(self.asn1Type(self.pythonString)) == self.pythonString
+        assert self.asn1Type(univ.OctetString(self.pythonString.encode(self.encoding), encoding=self.encoding)) == self.pythonString
+
+    def testAsOctets(self):
+        assert self.asn1String.asOctets() == self.pythonString.encode(self.encoding), 'testAsOctets() fails'
+
+    def testAsNumbers(self):
+        assert self.asn1String.asNumbers() == self.initializer, 'testAsNumbers() fails'
+
+    def testSeq(self):
+        assert self.asn1String[0] == self.pythonString[0], '__getitem__() fails'
+
+    def testEmpty(self):
+        try:
+            str(self.asn1Type())
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Value operation on ASN1 type tolerated'
+
+    def testAdd(self):
+        assert self.asn1String + self.pythonString.encode(self.encoding) == self.pythonString + self.pythonString, '__add__() fails'
+
+    def testRadd(self):
+        assert self.pythonString.encode(self.encoding) + self.asn1String == self.pythonString + self.pythonString, '__radd__() fails'
+
+    def testMul(self):
+        assert self.asn1String * 2 == self.pythonString * 2, '__mul__() fails'
+
+    def testRmul(self):
+        assert 2 * self.asn1String == 2 * self.pythonString, '__rmul__() fails'
+
+    def testContains(self):
+        assert self.pythonString in self.asn1String
+        assert self.pythonString + self.pythonString not in self.asn1String
+
+    if sys.version_info[:2] > (2, 4):
+        def testReverse(self):
+            assert list(reversed(self.asn1String)) == list(reversed(self.pythonString))
+
+
+class VisibleStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+    initializer = (97, 102)
+    encoding = 'us-ascii'
+    asn1Type = char.VisibleString
+
+
+class GeneralStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+    initializer = (169, 174)
+    encoding = 'iso-8859-1'
+    asn1Type = char.GeneralString
+
+
+class UTF8StringTestCase(AbstractStringTestCase, BaseTestCase):
+
+    initializer = (209, 132, 208, 176)
+    encoding = 'utf-8'
+    asn1Type = char.UTF8String
+
+
+class BMPStringTestCase(AbstractStringTestCase, BaseTestCase):
+
+    initializer = (4, 48, 4, 68)
+    encoding = 'utf-16-be'
+    asn1Type = char.BMPString
+
+
+if sys.version_info[0] > 2:
+
+    # Somehow comparison of UTF-32 encoded strings does not work in Py2
+
+    class UniversalStringTestCase(AbstractStringTestCase, BaseTestCase):
+        initializer = (0, 0, 4, 48, 0, 0, 4, 68)
+        encoding = 'utf-32-be'
+        asn1Type = char.UniversalString
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_constraint.py
@@ -0,0 +1,334 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import constraint, error
+
+
+class SingleValueConstraintTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.SingleValueConstraint(1, 2)
+        self.c2 = constraint.SingleValueConstraint(3, 4)
+
+    def testCmp(self):
+        assert self.c1 == self.c1, 'comparation fails'
+
+    def testHash(self):
+        assert hash(self.c1) != hash(self.c2), 'hash() fails'
+
+    def testGoodVal(self):
+        try:
+            self.c1(1)
+
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(4)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ContainedSubtypeConstraintTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ContainedSubtypeConstraint(
+            constraint.SingleValueConstraint(12)
+        )
+
+    def testGoodVal(self):
+        try:
+            self.c1(12)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(4)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ValueRangeConstraintTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ValueRangeConstraint(1, 4)
+
+    def testGoodVal(self):
+        try:
+            self.c1(1)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(-5)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ValueSizeConstraintTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ValueSizeConstraint(1, 2)
+
+    def testGoodVal(self):
+        try:
+            self.c1('a')
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1('abc')
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class PermittedAlphabetConstraintTestCase(SingleValueConstraintTestCase):
+    def setUp(self):
+        self.c1 = constraint.PermittedAlphabetConstraint('A', 'B', 'C')
+        self.c2 = constraint.PermittedAlphabetConstraint('DEF')
+
+    def testGoodVal(self):
+        try:
+            self.c1('A')
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1('E')
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ConstraintsIntersectionTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ConstraintsIntersection(
+            constraint.SingleValueConstraint(4),
+            constraint.ValueRangeConstraint(2, 4)
+        )
+
+    def testCmp1(self):
+        assert constraint.SingleValueConstraint(4) in self.c1, '__cmp__() fails'
+
+    def testCmp2(self):
+        assert constraint.SingleValueConstraint(5) not in self.c1, \
+            '__cmp__() fails'
+
+    def testCmp3(self):
+        c = constraint.ConstraintsUnion(constraint.ConstraintsIntersection(
+            constraint.SingleValueConstraint(4),
+            constraint.ValueRangeConstraint(2, 4))
+        )
+        assert self.c1 in c, '__cmp__() fails'
+
+    def testCmp4(self):
+        c = constraint.ConstraintsUnion(
+            constraint.ConstraintsIntersection(constraint.SingleValueConstraint(5))
+        )
+        assert self.c1 not in c, '__cmp__() fails'
+
+    def testGoodVal(self):
+        try:
+            self.c1(4)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(-5)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class InnerTypeConstraintTestCase(BaseTestCase):
+    def testConst1(self):
+        c = constraint.InnerTypeConstraint(
+            constraint.SingleValueConstraint(4)
+        )
+        try:
+            c(4, 32)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+        try:
+            c(5, 32)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+    def testConst2(self):
+        c = constraint.InnerTypeConstraint(
+            (0, constraint.SingleValueConstraint(4), 'PRESENT'),
+            (1, constraint.SingleValueConstraint(4), 'ABSENT')
+        )
+        try:
+            c(4, 0)
+        except error.ValueConstraintError:
+            raise
+            assert 0, 'constraint check fails'
+        try:
+            c(4, 1)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+        try:
+            c(3, 0)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+        # Constraints compositions
+
+
+class ConstraintsIntersectionRangeTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ConstraintsIntersection(
+            constraint.ValueRangeConstraint(1, 9),
+            constraint.ValueRangeConstraint(2, 5)
+        )
+
+    def testGoodVal(self):
+        try:
+            self.c1(3)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(0)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ConstraintsUnionTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ConstraintsUnion(
+            constraint.SingleValueConstraint(5),
+            constraint.ValueRangeConstraint(1, 3)
+        )
+
+    def testGoodVal(self):
+        try:
+            self.c1(2)
+            self.c1(5)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(-5)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+class ConstraintsExclusionTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.c1 = constraint.ConstraintsExclusion(
+            constraint.ValueRangeConstraint(2, 4)
+        )
+
+    def testGoodVal(self):
+        try:
+            self.c1(6)
+        except error.ValueConstraintError:
+            assert 0, 'constraint check fails'
+
+    def testBadVal(self):
+        try:
+            self.c1(2)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint check fails'
+
+
+# Constraints derivations
+
+class DirectDerivationTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.c1 = constraint.SingleValueConstraint(5)
+
+        self.c2 = constraint.ConstraintsUnion(
+            self.c1, constraint.ValueRangeConstraint(1, 3)
+        )
+
+    def testGoodVal(self):
+        assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
+        assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed'
+
+    def testBadVal(self):
+        assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed'
+        assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed'
+
+
+class IndirectDerivationTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.c1 = constraint.ConstraintsIntersection(
+            constraint.ValueRangeConstraint(1, 30)
+        )
+
+        self.c2 = constraint.ConstraintsIntersection(
+            self.c1, constraint.ValueRangeConstraint(1, 20)
+        )
+
+        self.c2 = constraint.ConstraintsIntersection(
+            self.c2, constraint.ValueRangeConstraint(1, 10)
+        )
+
+    def testGoodVal(self):
+        assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed'
+        assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed'
+
+    def testBadVal(self):
+        assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed'
+        assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed'
+
+# TODO: how to apply size constraints to constructed types?
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_namedtype.py
@@ -0,0 +1,147 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedtype, univ
+from pyasn1.error import PyAsn1Error
+
+
+class NamedTypeCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.e = namedtype.NamedType('age', univ.Integer(0))
+
+    def testIter(self):
+        n, t = self.e
+        assert n == 'age' or t == univ.Integer(), 'unpack fails'
+
+    def testRepr(self):
+        assert eval(repr(self.e), {'NamedType': namedtype.NamedType, 'Integer': univ.Integer}) == self.e, 'repr() fails'
+
+
+class NamedTypesCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.e = namedtype.NamedTypes(
+            namedtype.NamedType('first-name', univ.OctetString('')),
+            namedtype.OptionalNamedType('age', univ.Integer(0)),
+            namedtype.NamedType('family-name', univ.OctetString(''))
+        )
+
+    def testRepr(self):
+        assert eval(
+            repr(self.e), {
+                'NamedTypes': namedtype.NamedTypes,
+                'NamedType': namedtype.NamedType,
+                'OptionalNamedType': namedtype.OptionalNamedType,
+                'Integer': univ.Integer,
+                'OctetString': univ.OctetString
+            }
+        ) == self.e, 'repr() fails'
+
+    def testContains(self):
+        assert 'first-name' in self.e
+        assert '<missing>' not in self.e
+
+    # noinspection PyUnusedLocal
+    def testGetItem(self):
+        assert self.e[0] == namedtype.NamedType('first-name', univ.OctetString(''))
+
+    def testIter(self):
+        assert list(self.e) == ['first-name', 'age', 'family-name']
+
+    def testGetTypeByPosition(self):
+        assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
+            'getTypeByPosition() fails'
+
+    def testGetNameByPosition(self):
+        assert self.e.getNameByPosition(0) == 'first-name', \
+            'getNameByPosition() fails'
+
+    def testGetPositionByName(self):
+        assert self.e.getPositionByName('first-name') == 0, \
+            'getPositionByName() fails'
+
+    def testGetTypesNearPosition(self):
+        assert self.e.getTagMapNearPosition(0).presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString('')
+        }
+        assert self.e.getTagMapNearPosition(1).presentTypes == {
+            univ.Integer.tagSet: univ.Integer(0),
+            univ.OctetString.tagSet: univ.OctetString('')
+        }
+        assert self.e.getTagMapNearPosition(2).presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString('')
+        }
+
+    def testGetTagMap(self):
+        assert self.e.tagMap.presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString(''),
+            univ.Integer.tagSet: univ.Integer(0)
+        }
+
+    def testStrTagMap(self):
+        assert 'TagMap' in str(self.e.tagMap)
+        assert 'OctetString' in str(self.e.tagMap)
+        assert 'Integer' in str(self.e.tagMap)
+
+    def testReprTagMap(self):
+        assert 'TagMap' in repr(self.e.tagMap)
+        assert 'OctetString' in repr(self.e.tagMap)
+        assert 'Integer' in repr(self.e.tagMap)
+
+    def testGetTagMapWithDups(self):
+        try:
+            self.e.tagMapUnique[0]
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'Duped types not noticed'
+
+    def testGetPositionNearType(self):
+        assert self.e.getPositionNearType(univ.OctetString.tagSet, 0) == 0
+        assert self.e.getPositionNearType(univ.Integer.tagSet, 1) == 1
+        assert self.e.getPositionNearType(univ.OctetString.tagSet, 2) == 2
+
+
+class OrderedNamedTypesCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.e = namedtype.NamedTypes(
+            namedtype.NamedType('first-name', univ.OctetString('')),
+            namedtype.NamedType('age', univ.Integer(0))
+        )
+
+    def testGetTypeByPosition(self):
+        assert self.e.getTypeByPosition(0) == univ.OctetString(''), \
+            'getTypeByPosition() fails'
+
+
+class DuplicateNamedTypesCaseBase(BaseTestCase):
+    def testDuplicateDefaultTags(self):
+        nt = namedtype.NamedTypes(
+            namedtype.NamedType('first-name', univ.Any()),
+            namedtype.NamedType('age', univ.Any())
+        )
+
+        assert isinstance(nt.tagMap, namedtype.NamedTypes.PostponedError)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_namedval.py
@@ -0,0 +1,58 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import namedval
+
+
+class NamedValuesCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.e = namedval.NamedValues(('off', 0), ('on', 1))
+
+    def testDict(self):
+        assert set(self.e.items()) == set([('off', 0), ('on', 1)])
+        assert set(self.e.keys()) == set(['off', 'on'])
+        assert set(self.e) == set(['off', 'on'])
+        assert set(self.e.values()) == set([0, 1])
+        assert 'on' in self.e and 'off' in self.e and 'xxx' not in self.e
+        assert 0 in self.e and 1 in self.e and 2 not in self.e
+
+    def testInit(self):
+        assert namedval.NamedValues(off=0, on=1) == {'off': 0, 'on': 1}
+        assert namedval.NamedValues('off', 'on') == {'off': 0, 'on': 1}
+        assert namedval.NamedValues(('c', 0)) == {'c': 0}
+        assert namedval.NamedValues('a', 'b', ('c', 0), d=1) == {'c': 0, 'd': 1, 'a': 2, 'b': 3}
+
+    def testLen(self):
+        assert len(self.e) == 2
+        assert len(namedval.NamedValues()) == 0
+
+    def testAdd(self):
+        assert namedval.NamedValues(off=0) + namedval.NamedValues(on=1) == {'off': 0, 'on': 1}
+
+    def testClone(self):
+        assert namedval.NamedValues(off=0).clone(('on', 1)) == {'off': 0, 'on': 1}
+        assert namedval.NamedValues(off=0).clone(on=1) == {'off': 0, 'on': 1}
+
+    def testStrRepr(self):
+        assert str(self.e)
+        assert repr(self.e)
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_tag.py
@@ -0,0 +1,138 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import tag
+
+
+class TagTestCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.t1 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
+        self.t2 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3)
+
+
+class TagReprTestCase(TagTestCaseBase):
+    def testRepr(self):
+        assert eval(repr(self.t1), {'Tag': tag.Tag}) == self.t1, 'repr() fails'
+
+
+class TagCmpTestCase(TagTestCaseBase):
+    def testCmp(self):
+        assert self.t1 == self.t2, 'tag comparation fails'
+
+    def testHash(self):
+        assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails'
+
+    def testSequence(self):
+        assert self.t1[0] == self.t2[0] and \
+               self.t1[1] == self.t2[1] and \
+               self.t1[2] == self.t2[2], 'tag sequence protocol fails'
+
+
+class TagSetTestCaseBase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.ts1 = tag.initTagSet(
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+        )
+
+        self.ts2 = tag.initTagSet(
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+        )
+
+
+class TagSetReprTestCase(TagSetTestCaseBase):
+    def testRepr(self):
+        assert eval(repr(self.ts1), {'TagSet': tag.TagSet, 'Tag': tag.Tag}) == self.ts1, 'repr() fails'
+
+
+class TagSetCmpTestCase(TagSetTestCaseBase):
+    def testCmp(self):
+        assert self.ts1 == self.ts2, 'tag set comparation fails'
+
+    def testHash(self):
+        assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails'
+
+    def testLen(self):
+        assert len(self.ts1) == len(self.ts2), 'tag length comparation fails'
+
+
+class TaggingTestSuite(TagSetTestCaseBase):
+    def testImplicitTag(self):
+        t = self.ts1.tagImplicitly(
+            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
+        )
+        assert t == tag.TagSet(
+            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14)
+        ), 'implicit tagging went wrong'
+
+    def testExplicitTag(self):
+        t = self.ts1.tagExplicitly(
+            tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 32)
+        )
+        assert t == tag.TagSet(
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassPrivate, tag.tagFormatConstructed, 32)
+        ), 'explicit tagging went wrong'
+
+
+class TagSetAddTestSuite(TagSetTestCaseBase):
+    def testAdd(self):
+        t = self.ts1 + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
+        assert t == tag.TagSet(
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)
+        ), 'TagSet.__add__() fails'
+
+    def testRadd(self):
+        t = tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + self.ts1
+        assert t == tag.TagSet(
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+            tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+        ), 'TagSet.__radd__() fails'
+
+
+class SuperTagSetTestCase(TagSetTestCaseBase):
+    def testSuperTagCheck1(self):
+        assert self.ts1.isSuperTagSetOf(
+            tag.TagSet(
+                tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+                tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
+            )), 'isSuperTagSetOf() fails'
+
+    def testSuperTagCheck2(self):
+        assert not self.ts1.isSuperTagSetOf(
+            tag.TagSet(
+                tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12),
+                tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 13)
+            )), 'isSuperTagSetOf() fails'
+
+    def testSuperTagCheck3(self):
+        assert self.ts1.isSuperTagSetOf(
+            tag.TagSet((), tag.Tag(tag.tagClassUniversal,
+                                   tag.tagFormatSimple, 12))
+        ), 'isSuperTagSetOf() fails'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_univ.py
@@ -0,0 +1,1503 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import math
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import univ, tag, constraint, namedtype, namedval, error
+from pyasn1.compat.octets import str2octs, ints2octs, octs2ints
+from pyasn1.error import PyAsn1Error
+
+
+class NoValueTestCase(BaseTestCase):
+    def testSingleton(self):
+        assert univ.NoValue() is univ.NoValue(), 'NoValue is not a singleton'
+
+    def testRepr(self):
+        try:
+            repr(univ.noValue)
+
+        except PyAsn1Error:
+            assert False, 'repr() on NoValue object fails'
+
+    def testIsInstance(self):
+        try:
+            assert isinstance(univ.noValue, univ.NoValue), 'isinstance() on NoValue() object fails'
+
+        except PyAsn1Error:
+            assert False, 'isinstance() on NoValue object fails'
+
+    def testStr(self):
+        try:
+            str(univ.noValue)
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'str() works for NoValue object'
+
+    def testLen(self):
+        try:
+            len(univ.noValue)
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'len() works for NoValue object'
+
+    def testCmp(self):
+        try:
+            univ.noValue == 1
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'comparison works for NoValue object'
+
+    def testSubs(self):
+        try:
+            univ.noValue[0]
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, '__getitem__() works for NoValue object'
+
+    def testKey(self):
+        try:
+            univ.noValue['key']
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, '__getitem__() works for NoValue object'
+
+    def testKeyAssignment(self):
+        try:
+            univ.noValue['key'] = 123
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, '__setitem__() works for NoValue object'
+
+    def testInt(self):
+        try:
+            int(univ.noValue)
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'integer conversion works for NoValue object'
+
+    def testAdd(self):
+        try:
+            univ.noValue + univ.noValue
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'addition works for NoValue object'
+
+    def testBitShift(self):
+        try:
+            univ.noValue << 1
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'bitshift works for NoValue object'
+
+    def testBooleanEvaluation(self):
+        try:
+            if univ.noValue:
+                pass
+
+        except PyAsn1Error:
+            pass
+
+        else:
+            assert False, 'boolean evaluation works for NoValue object'
+    
+    def testSizeOf(self):
+        try:
+            if hasattr(sys, 'getsizeof'):
+                sys.getsizeof(univ.noValue)
+
+        except PyAsn1Error:
+            assert False, 'sizeof failed for NoValue object'
+
+
+class IntegerTestCase(BaseTestCase):
+    def testStr(self):
+        assert str(univ.Integer(1)) in ('1', '1L'), 'str() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.Integer(123)), {'Integer': univ.Integer}) == univ.Integer(123), 'repr() fails'
+
+    def testAnd(self):
+        assert univ.Integer(1) & 0 == 0, '__and__() fails'
+
+    def testOr(self):
+        assert univ.Integer(1) | 0 == 1, '__or__() fails'
+
+    def testXor(self):
+        assert univ.Integer(1) ^ 0 == 1, '__xor__() fails'
+
+    def testRand(self):
+        assert 0 & univ.Integer(1) == 0, '__rand__() fails'
+
+    def testRor(self):
+        assert 0 | univ.Integer(1) == 1, '__ror__() fails'
+
+    def testRxor(self):
+        assert 0 ^ univ.Integer(1) == 1, '__rxor__() fails'
+
+    def testAdd(self):
+        assert univ.Integer(-4) + 6 == 2, '__add__() fails'
+
+    def testRadd(self):
+        assert 4 + univ.Integer(5) == 9, '__radd__() fails'
+
+    def testSub(self):
+        assert univ.Integer(3) - 6 == -3, '__sub__() fails'
+
+    def testRsub(self):
+        assert 6 - univ.Integer(3) == 3, '__rsub__() fails'
+
+    def testMul(self):
+        assert univ.Integer(3) * -3 == -9, '__mul__() fails'
+
+    def testRmul(self):
+        assert 2 * univ.Integer(3) == 6, '__rmul__() fails'
+
+    def testDivInt(self):
+        assert univ.Integer(4) / 2 == 2, '__div__() fails'
+
+    if sys.version_info[0] > 2:
+        def testDivFloat(self):
+            assert univ.Integer(3) / 2 == 1.5, '__div__() fails'
+
+        def testRdivFloat(self):
+            assert 3 / univ.Integer(2) == 1.5, '__rdiv__() fails'
+    else:
+        def testDivFloat(self):
+            assert univ.Integer(3) / 2 == 1, '__div__() fails'
+
+        def testRdivFloat(self):
+            assert 3 / univ.Integer(2) == 1, '__rdiv__() fails'
+
+    def testRdivInt(self):
+        assert 6 / univ.Integer(3) == 2, '__rdiv__() fails'
+
+    if sys.version_info[0] > 2:
+        def testTrueDiv(self):
+            assert univ.Integer(3) / univ.Integer(2) == 1.5, '__truediv__() fails'
+
+    def testFloorDiv(self):
+        assert univ.Integer(3) // univ.Integer(2) == 1, '__floordiv__() fails'
+
+    def testMod(self):
+        assert univ.Integer(3) % 2 == 1, '__mod__() fails'
+
+    def testRmod(self):
+        assert 4 % univ.Integer(3) == 1, '__rmod__() fails'
+
+    def testPow(self):
+        assert univ.Integer(3) ** 2 == 9, '__pow__() fails'
+
+    def testRpow(self):
+        assert 2 ** univ.Integer(2) == 4, '__rpow__() fails'
+
+    def testLshift(self):
+        assert univ.Integer(1) << 1 == 2, '<< fails'
+
+    def testRshift(self):
+        assert univ.Integer(2) >> 1 == 1, '>> fails'
+
+    def testInt(self):
+        assert int(univ.Integer(3)) == 3, '__int__() fails'
+
+    def testLong(self):
+        assert int(univ.Integer(8)) == 8, '__long__() fails'
+
+    def testFloat(self):
+        assert float(univ.Integer(4)) == 4.0, '__float__() fails'
+
+    def testPos(self):
+        assert +univ.Integer(1) == 1, '__pos__() fails'
+
+    def testNeg(self):
+        assert -univ.Integer(1) == -1, '__neg__() fails'
+
+    def testInvert(self):
+        assert ~univ.Integer(1) == -2, '__invert__() fails'
+
+    def testRound(self):
+        assert round(univ.Integer(1), 3) == 1.0, '__round__() fails'
+
+    def testFloor(self):
+        assert math.floor(univ.Integer(1)) == 1, '__floor__() fails'
+
+    def testCeil(self):
+        assert math.ceil(univ.Integer(1)) == 1, '__ceil__() fails'
+
+    if sys.version_info[0:2] > (2, 5):
+        def testTrunc(self):
+            assert math.trunc(univ.Integer(1)) == 1, '__trunc__() fails'
+
+    def testPrettyIn(self):
+        assert univ.Integer('3') == 3, 'prettyIn() fails'
+
+    def testTag(self):
+        assert univ.Integer().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
+        )
+
+    def testNamedVals(self):
+
+        class Integer(univ.Integer):
+            namedValues = univ.Integer.namedValues.clone(('asn1', 1))
+
+        assert Integer('asn1') == 1, 'named val fails'
+        assert str(Integer('asn1')) != 'asn1', 'named val __str__() fails'
+
+    def testSubtype(self):
+        assert univ.Integer().subtype(
+            value=1,
+            implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2),
+            subtypeSpec=constraint.SingleValueConstraint(1, 3)
+        ) == univ.Integer(
+            value=1,
+            tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
+                                      tag.tagFormatSimple, 2)),
+            subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3))
+        )
+
+
+class BooleanTestCase(BaseTestCase):
+    def testTruth(self):
+        assert univ.Boolean(True) and univ.Boolean(1), 'Truth initializer fails'
+
+    def testFalse(self):
+        assert not univ.Boolean(False) and not univ.Boolean(0), 'False initializer fails'
+
+    def testStr(self):
+        assert str(univ.Boolean(1)) in ('1', '1L'), 'str() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.Boolean(1)), {'Boolean': univ.Boolean}) == univ.Boolean(1), 'repr() fails'
+
+    def testTag(self):
+        assert univ.Boolean().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01)
+        )
+
+    def testConstraints(self):
+
+        class Boolean(univ.Boolean):
+            pass
+
+        try:
+            Boolean(2)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint fail'
+
+
+class BitStringTestCase(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.b = univ.BitString(
+            namedValues=namedval.NamedValues(('Active', 0), ('Urgent', 1))
+        )
+
+    def testBinDefault(self):
+
+        class BinDefault(univ.BitString):
+            defaultBinValue = '1010100110001010'
+
+        assert BinDefault() == univ.BitString(binValue='1010100110001010')
+
+    def testHexDefault(self):
+
+        class HexDefault(univ.BitString):
+            defaultHexValue = 'A98A'
+
+        assert HexDefault() == univ.BitString(hexValue='A98A')
+
+    def testSet(self):
+        assert self.b.clone('Active') == (1,)
+        assert self.b.clone('Urgent') == (0, 1)
+        assert self.b.clone('Urgent, Active') == (1, 1)
+        assert self.b.clone("'1010100110001010'B") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+        assert self.b.clone("'A98A'H") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+        assert self.b.clone(binValue='1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+        assert self.b.clone(hexValue='A98A') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+        assert self.b.clone('1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0)
+        assert self.b.clone((1, 0, 1)) == (1, 0, 1)
+
+    def testStr(self):
+        assert str(self.b.clone('Urgent')) == '01'
+
+    def testRepr(self):
+        assert eval(repr(self.b.clone('Urgent,Active')), {'BitString': univ.BitString}) == self.b.clone(
+            'Urgent,Active'), 'repr() fails'
+
+    def testTag(self):
+        assert univ.BitString().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
+        )
+
+    def testLen(self):
+        assert len(self.b.clone("'A98A'H")) == 16
+
+    def testGetItem(self):
+        assert self.b.clone("'A98A'H")[0] == 1
+        assert self.b.clone("'A98A'H")[1] == 0
+        assert self.b.clone("'A98A'H")[2] == 1
+
+    if sys.version_info[:2] > (2, 4):
+        def testReverse(self):
+            assert list(reversed(univ.BitString([0, 0, 1]))) == list(univ.BitString([1, 0, 0]))
+
+    def testAsOctets(self):
+        assert self.b.clone(hexValue='A98A').asOctets() == ints2octs((0xa9, 0x8a)), 'testAsOctets() fails'
+
+    def testAsInts(self):
+        assert self.b.clone(hexValue='A98A').asNumbers() == (0xa9, 0x8a), 'testAsNumbers() fails'
+
+    def testMultipleOfEightPadding(self):
+        assert self.b.clone((1, 0, 1)).asNumbers() == (5,)
+
+    def testAsInteger(self):
+        assert self.b.clone('11000000011001').asInteger() == 12313
+        assert self.b.clone('1100110011011111').asInteger() == 52447
+
+    def testStaticDef(self):
+
+        class BitString(univ.BitString):
+            pass
+
+        assert BitString('11000000011001').asInteger() == 12313
+
+
+class OctetStringWithUnicodeMixIn(object):
+
+    initializer = ()
+    encoding = 'us-ascii'
+
+    def setUp(self):
+        self.pythonString = ints2octs(self.initializer).decode(self.encoding)
+        self.encodedPythonString = self.pythonString.encode(self.encoding)
+        self.numbersString = tuple(octs2ints(self.encodedPythonString))
+
+    def testInit(self):
+        assert univ.OctetString(self.encodedPythonString) == self.encodedPythonString, '__init__() fails'
+
+    def testInitFromAsn1(self):
+            assert univ.OctetString(univ.OctetString(self.encodedPythonString)) == self.encodedPythonString
+            assert univ.OctetString(univ.Integer(123)) == univ.OctetString('123')
+
+    def testSerialized(self):
+        if sys.version_info[0] < 3:
+            assert str(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+        else:
+            assert bytes(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+
+    def testPrintable(self):
+        if sys.version_info[0] < 3:
+            assert str(univ.OctetString(self.encodedPythonString, encoding=self.encoding)) == self.encodedPythonString, '__str__() fails'
+            assert unicode(univ.OctetString(self.pythonString, encoding=self.encoding)) == self.pythonString, 'unicode init fails'
+        else:
+            assert str(univ.OctetString(self.pythonString, encoding=self.encoding)) == self.pythonString, 'unicode init fails'
+
+    def testSeq(self):
+        assert univ.OctetString(self.encodedPythonString)[0] == self.encodedPythonString[0], '__getitem__() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.OctetString('abc')), {'OctetString': univ.OctetString}) == univ.OctetString('abc'), 'repr() fails'
+
+    def testAsOctets(self):
+        assert univ.OctetString(self.encodedPythonString).asOctets() == self.encodedPythonString, 'testAsOctets() fails'
+
+    def testAsInts(self):
+        assert univ.OctetString(self.encodedPythonString).asNumbers() == self.numbersString, 'testAsNumbers() fails'
+
+    def testAdd(self):
+        assert univ.OctetString(self.encodedPythonString) + self.encodedPythonString == self.encodedPythonString + self.encodedPythonString, '__add__() fails'
+
+    def testRadd(self):
+        assert self.encodedPythonString + univ.OctetString(self.encodedPythonString) == self.encodedPythonString + self.encodedPythonString, '__radd__() fails'
+
+    def testMul(self):
+        assert univ.OctetString(self.encodedPythonString) * 2 == self.encodedPythonString * 2, '__mul__() fails'
+
+    def testRmul(self):
+        assert 2 * univ.OctetString(self.encodedPythonString) == 2 * self.encodedPythonString, '__rmul__() fails'
+
+    def testContains(self):
+        s = univ.OctetString(self.encodedPythonString)
+        assert self.encodedPythonString in s
+        assert self.encodedPythonString * 2 not in s
+
+    if sys.version_info[:2] > (2, 4):
+       def testReverse(self):
+           assert list(reversed(univ.OctetString(self.encodedPythonString))) == list(reversed(self.encodedPythonString))
+
+
+class OctetStringWithAsciiTestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+    initializer = (97, 102)
+    encoding = 'us-ascii'
+
+
+class OctetStringWithUtf8TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+    initializer = (208, 176, 208, 177, 208, 178)
+    encoding = 'utf-8'
+
+
+class OctetStringWithUtf16TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+    initializer = (4, 48, 4, 49, 4, 50)
+    encoding = 'utf-16-be'
+
+
+if sys.version_info[0] > 2:
+
+    # Somehow comparison of UTF-32 encoded strings does not work in Py2
+
+    class OctetStringWithUtf32TestCase(OctetStringWithUnicodeMixIn, BaseTestCase):
+        initializer = (0, 0, 4, 48, 0, 0, 4, 49, 0, 0, 4, 50)
+        encoding = 'utf-32-be'
+
+
+class OctetStringTestCase(BaseTestCase):
+
+    def testBinDefault(self):
+
+        class BinDefault(univ.OctetString):
+            defaultBinValue = '1000010111101110101111000000111011'
+
+        assert BinDefault() == univ.OctetString(binValue='1000010111101110101111000000111011')
+
+    def testHexDefault(self):
+
+        class HexDefault(univ.OctetString):
+            defaultHexValue = 'FA9823C43E43510DE3422'
+
+        assert HexDefault() == univ.OctetString(hexValue='FA9823C43E43510DE3422')
+
+    def testBinStr(self):
+        assert univ.OctetString(binValue="1000010111101110101111000000111011") == ints2octs((133, 238, 188, 14, 192)), 'bin init fails'
+
+    def testHexStr(self):
+        assert univ.OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32)), 'hex init fails'
+
+    def testTuple(self):
+        assert univ.OctetString((1, 2, 3, 4, 5)) == ints2octs((1, 2, 3, 4, 5)), 'tuple init failed'
+
+    def testRepr(self):
+        assert eval(repr(univ.OctetString('abc')), {'OctetString': univ.OctetString}) == univ.OctetString('abc'), 'repr() fails'
+
+    def testEmpty(self):
+        try:
+            str(univ.OctetString())
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'empty OctetString() not reported'
+
+    def testTag(self):
+        assert univ.OctetString().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
+        )
+
+    def testStaticDef(self):
+
+        class OctetString(univ.OctetString):
+            pass
+
+        assert OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs((250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32))
+
+
+class Null(BaseTestCase):
+    def testStr(self):
+        assert str(univ.Null('')) == '', 'str() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.Null()), {'Null': univ.Null}) == univ.Null(), 'repr() fails'
+
+    def testTag(self):
+        assert univ.Null().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
+        )
+
+    def testConstraints(self):
+        try:
+            univ.Null(2)
+        except error.ValueConstraintError:
+            pass
+        else:
+            assert 0, 'constraint fail'
+
+    def testStaticDef(self):
+
+        class Null(univ.Null):
+            pass
+
+        assert not Null()
+
+
+class RealTestCase(BaseTestCase):
+    def testFloat4BinEnc(self):
+        assert univ.Real((0.25, 2, 3)) == 2.0, 'float initializer for binary encoding fails'
+
+    def testStr(self):
+        assert str(univ.Real(1.0)) == '1.0', 'str() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.Real(-4.1)), {'Real': univ.Real}) == univ.Real(-4.1), 'repr() fails'
+        assert repr(univ.Real(-4.1)) == 'Real((-41, 10, -1))', 'repr() fails'
+        assert eval(repr(univ.Real('inf')), {'Real': univ.Real}) == univ.Real('inf'), 'repr() fails'
+        assert repr(univ.Real('inf')) == 'Real(\'inf\')', 'repr() fails'
+
+    def testAdd(self):
+        assert univ.Real(-4.1) + 1.4 == -2.7, '__add__() fails'
+
+    def testRadd(self):
+        assert 4 + univ.Real(0.5) == 4.5, '__radd__() fails'
+
+    def testSub(self):
+        assert univ.Real(3.9) - 1.7 == 2.2, '__sub__() fails'
+
+    def testRsub(self):
+        assert 6.1 - univ.Real(0.1) == 6, '__rsub__() fails'
+
+    def testMul(self):
+        assert univ.Real(3.0) * -3 == -9, '__mul__() fails'
+
+    def testRmul(self):
+        assert 2 * univ.Real(3.0) == 6, '__rmul__() fails'
+
+    def testDiv(self):
+        assert univ.Real(3.0) / 2 == 1.5, '__div__() fails'
+
+    def testRdiv(self):
+        assert 6 / univ.Real(3.0) == 2, '__rdiv__() fails'
+
+    def testMod(self):
+        assert univ.Real(3.0) % 2 == 1, '__mod__() fails'
+
+    def testRmod(self):
+        assert 4 % univ.Real(3.0) == 1, '__rmod__() fails'
+
+    def testPow(self):
+        assert univ.Real(3.0) ** 2 == 9, '__pow__() fails'
+
+    def testRpow(self):
+        assert 2 ** univ.Real(2.0) == 4, '__rpow__() fails'
+
+    def testInt(self):
+        assert int(univ.Real(3.0)) == 3, '__int__() fails'
+
+    def testLong(self):
+        assert int(univ.Real(8.0)) == 8, '__long__() fails'
+
+    def testFloat(self):
+        assert float(univ.Real(4.0)) == 4.0, '__float__() fails'
+
+    def testPrettyIn(self):
+        assert univ.Real((3, 10, 0)) == 3, 'prettyIn() fails'
+
+    # infinite float values
+    def testStrInf(self):
+        assert str(univ.Real('inf')) == 'inf', 'str() fails'
+
+    def testAddInf(self):
+        assert univ.Real('inf') + 1 == float('inf'), '__add__() fails'
+
+    def testRaddInf(self):
+        assert 1 + univ.Real('inf') == float('inf'), '__radd__() fails'
+
+    def testIntInf(self):
+        try:
+            assert int(univ.Real('inf'))
+        except OverflowError:
+            pass
+        else:
+            assert 0, '__int__() fails'
+
+    def testLongInf(self):
+        try:
+            assert int(univ.Real('inf'))
+        except OverflowError:
+            pass
+        else:
+            assert 0, '__long__() fails'
+        assert int(univ.Real(8.0)) == 8, '__long__() fails'
+
+    def testFloatInf(self):
+        assert float(univ.Real('-inf')) == float('-inf'), '__float__() fails'
+
+    def testPrettyInInf(self):
+        assert univ.Real(float('inf')) == float('inf'), 'prettyIn() fails'
+
+    def testPlusInf(self):
+        assert univ.Real('inf').isPlusInf, 'isPlusInfinity failed'
+
+    def testMinusInf(self):
+        assert univ.Real('-inf').isMinusInf, 'isMinusInfinity failed'
+
+    def testPos(self):
+        assert +univ.Real(1.0) == 1.0, '__pos__() fails'
+
+    def testNeg(self):
+        assert -univ.Real(1.0) == -1.0, '__neg__() fails'
+
+    def testRound(self):
+        assert round(univ.Real(1.123), 2) == 1.12, '__round__() fails'
+
+    def testFloor(self):
+        assert math.floor(univ.Real(1.6)) == 1.0, '__floor__() fails'
+
+    def testCeil(self):
+        assert math.ceil(univ.Real(1.2)) == 2.0, '__ceil__() fails'
+
+    if sys.version_info[0:2] > (2, 5):
+        def testTrunc(self):
+            assert math.trunc(univ.Real(1.1)) == 1.0, '__trunc__() fails'
+
+    def testTag(self):
+        assert univ.Real().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
+        )
+
+    def testStaticDef(self):
+
+        class Real(univ.Real):
+            pass
+
+        assert Real(1.0) == 1.0
+
+
+class ObjectIdentifier(BaseTestCase):
+    def testStr(self):
+        assert str(univ.ObjectIdentifier((1, 3, 6))) == '1.3.6', 'str() fails'
+
+    def testRepr(self):
+        assert eval(repr(univ.ObjectIdentifier('1.3.6')),
+                    {'ObjectIdentifier': univ.ObjectIdentifier}) == univ.ObjectIdentifier('1.3.6'), 'repr() fails'
+
+    def testEq(self):
+        assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), '__cmp__() fails'
+
+    def testAdd(self):
+        assert univ.ObjectIdentifier((1, 3)) + (6,) == (1, 3, 6), '__add__() fails'
+
+    def testRadd(self):
+        assert (1,) + univ.ObjectIdentifier((3, 6)) == (1, 3, 6), '__radd__() fails'
+
+    def testLen(self):
+        assert len(univ.ObjectIdentifier((1, 3))) == 2, '__len__() fails'
+
+    def testPrefix(self):
+        o = univ.ObjectIdentifier('1.3.6')
+        assert o.isPrefixOf((1, 3, 6)), 'isPrefixOf() fails'
+        assert o.isPrefixOf((1, 3, 6, 1)), 'isPrefixOf() fails'
+        assert not o.isPrefixOf((1, 3)), 'isPrefixOf() fails'
+
+    def testInput1(self):
+        assert univ.ObjectIdentifier('1.3.6') == (1, 3, 6), 'prettyIn() fails'
+
+    def testInput2(self):
+        assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), 'prettyIn() fails'
+
+    def testInput3(self):
+        assert univ.ObjectIdentifier(univ.ObjectIdentifier('1.3') + (6,)) == (1, 3, 6), 'prettyIn() fails'
+
+    def testUnicode(self):
+        s = '1.3.6'
+        if sys.version_info[0] < 3:
+            s = s.decode()
+        assert univ.ObjectIdentifier(s) == (1, 3, 6), 'unicode init fails'
+
+    def testTag(self):
+        assert univ.ObjectIdentifier().tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
+        )
+
+    def testContains(self):
+        s = univ.ObjectIdentifier('1.3.6.1234.99999')
+        assert 1234 in s
+        assert 4321 not in s
+
+    def testStaticDef(self):
+
+        class ObjectIdentifier(univ.ObjectIdentifier):
+            pass
+
+        assert str(ObjectIdentifier((1, 3, 6))) == '1.3.6'
+
+
+class SequenceOf(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s1 = univ.SequenceOf(
+            componentType=univ.OctetString('')
+        )
+        self.s2 = self.s1.clone()
+
+    def testRepr(self):
+        assert eval(repr(self.s1.clone().setComponents('a', 'b')),
+                    {'SequenceOf': univ.SequenceOf,
+                     'OctetString': univ.OctetString}) == self.s1.clone().setComponents(
+            'a', 'b'), 'repr() fails'
+
+    def testTag(self):
+        assert self.s1.tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+        ), 'wrong tagSet'
+
+    def testSeq(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        assert self.s1[0] == str2octs('abc'), 'set by idx fails'
+        self.s1[0] = 'cba'
+        assert self.s1[0] == str2octs('cba'), 'set by idx fails'
+
+    def testCmp(self):
+        self.s1.clear()
+        self.s1.setComponentByPosition(0, 'abc')
+        self.s2.clear()
+        self.s2.setComponentByPosition(0, univ.OctetString('abc'))
+        assert self.s1 == self.s2, '__cmp__() fails'
+
+    def testSubtypeSpec(self):
+        s = self.s1.clone(subtypeSpec=constraint.ConstraintsUnion(
+            constraint.SingleValueConstraint(str2octs('abc'))
+        ))
+        try:
+            s.setComponentByPosition(0, univ.OctetString('abc'))
+        except PyAsn1Error:
+            assert 0, 'constraint fails'
+        try:
+            s.setComponentByPosition(1, univ.OctetString('Abc'))
+        except PyAsn1Error:
+            try:
+                s.setComponentByPosition(1, univ.OctetString('Abc'),
+                                         verifyConstraints=False)
+            except PyAsn1Error:
+                assert 0, 'constraint failes with verifyConstraints=True'
+        else:
+            assert 0, 'constraint fails'
+
+    def testComponentTagsMatching(self):
+        s = self.s1.clone()
+        s.strictConstraints = True  # This requires types equality
+        o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12))
+        try:
+            s.setComponentByPosition(0, o)
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'inner supertype tag allowed'
+
+    def testComponentConstraintsMatching(self):
+        s = self.s1.clone()
+        o = univ.OctetString().subtype(
+            subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba'))))
+        s.strictConstraints = True  # This requires types equality
+        try:
+            s.setComponentByPosition(0, o.clone('cba'))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'inner supertype constraint allowed'
+        s.strictConstraints = False  # This requires subtype relationships
+        try:
+            s.setComponentByPosition(0, o.clone('cba'))
+        except PyAsn1Error:
+            assert 0, 'inner supertype constraint disallowed'
+        else:
+            pass
+
+    def testSizeSpec(self):
+        s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion(
+            constraint.ValueSizeConstraint(1, 1)
+        ))
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        try:
+            s.verifySizeSpec()
+        except PyAsn1Error:
+            assert 0, 'size spec fails'
+        s.setComponentByPosition(1, univ.OctetString('abc'))
+        try:
+            s.verifySizeSpec()
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'size spec fails'
+
+    def testGetComponentTagMap(self):
+        assert self.s1.componentType.tagMap.presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString('')
+        }
+
+    def testSubtype(self):
+        self.s1.clear()
+        assert self.s1.subtype(
+            implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2),
+            subtypeSpec=constraint.SingleValueConstraint(1, 3),
+            sizeSpec=constraint.ValueSizeConstraint(0, 1)
+        ) == self.s1.clone(
+            tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate,
+                                      tag.tagFormatSimple, 2)),
+            subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3)),
+            sizeSpec=constraint.ValueSizeConstraint(0, 1)
+        )
+
+    def testClone(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        s = self.s1.clone()
+        assert len(s) == 0
+        s = self.s1.clone(cloneValueFlag=1)
+        assert len(s) == 1
+        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+
+    def testSetComponents(self):
+        assert self.s1.clone().setComponents('abc', 'def') == \
+               self.s1.setComponentByPosition(0, 'abc').setComponentByPosition(1, 'def')
+
+    def testGetItem(self):
+        s = self.s1.clone()
+        s.append('xxx')
+        assert s[0]
+
+        try:
+            s[2]
+
+        except IndexError:
+            pass
+
+        else:
+            assert False, 'IndexError not raised'
+
+        # this is a deviation from standart sequence protocol
+        assert not s[1]
+
+    def testSetItem(self):
+        s = self.s1.clone()
+        s.append('xxx')
+
+        try:
+
+            s[2] = 'xxx'
+
+        except IndexError:
+            pass
+
+        else:
+            assert False, 'IndexError not raised'
+
+    def testAppend(self):
+        self.s1.clear()
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        assert len(self.s1) == 1
+        self.s1.append('def')
+        assert len(self.s1) == 2
+        assert list(self.s1) == [str2octs(x) for x in ['abc', 'def']]
+
+    def testExtend(self):
+        self.s1.clear()
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        assert len(self.s1) == 1
+        self.s1.extend(['def', 'ghi'])
+        assert len(self.s1) == 3
+        assert list(self.s1) == [str2octs(x) for x in ['abc', 'def', 'ghi']]
+
+    def testCount(self):
+        self.s1.clear()
+        for x in ['abc', 'def', 'abc']:
+            self.s1.append(x)
+        assert self.s1.count(str2octs('abc')) == 2
+        assert self.s1.count(str2octs('def')) == 1
+        assert self.s1.count(str2octs('ghi')) == 0
+
+    def testIndex(self):
+        self.s1.clear()
+        for x in ['abc', 'def', 'abc']:
+            self.s1.append(x)
+        assert self.s1.index(str2octs('abc')) == 0
+        assert self.s1.index(str2octs('def')) == 1
+        assert self.s1.index(str2octs('abc'), 1) == 2
+
+    def testSort(self):
+        self.s1.clear()
+        self.s1[0] = 'b'
+        self.s1[1] = 'a'
+        assert list(self.s1) == [str2octs('b'), str2octs('a')]
+        self.s1.sort()
+        assert list(self.s1) == [str2octs('a'), str2octs('b')]
+
+    def testStaticDef(self):
+
+        class SequenceOf(univ.SequenceOf):
+            componentType = univ.OctetString('')
+
+        s = SequenceOf()
+        s[0] = 'abc'
+        assert len(s) == 1
+        assert s == [str2octs('abc')]
+
+    def testLegacyInitializer(self):
+        n = univ.SequenceOf(
+            componentType=univ.OctetString()
+        )
+        o = univ.SequenceOf(
+            univ.OctetString()  # this is the old way
+        )
+
+        assert n.isSameTypeWith(o) and o.isSameTypeWith(n)
+
+        n[0] = 'fox'
+        o[0] = 'fox'
+
+        assert n == o
+
+class Sequence(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s1 = univ.Sequence(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString('')),
+                namedtype.OptionalNamedType('nick', univ.OctetString('')),
+                namedtype.DefaultedNamedType('age', univ.Integer(34))
+            )
+        )
+
+    def testRepr(self):
+        assert eval(
+            repr(self.s1.clone().setComponents('a', 'b')),
+            {'Sequence': univ.Sequence,
+             'OctetString': univ.OctetString,
+             'Integer': univ.Integer,
+             'NamedTypes': namedtype.NamedTypes,
+             'NamedType': namedtype.NamedType,
+             'OptionalNamedType': namedtype.OptionalNamedType,
+             'DefaultedNamedType': namedtype.DefaultedNamedType}
+        ) == self.s1.clone().setComponents('a', 'b'), 'repr() fails'
+
+    def testTag(self):
+        assert self.s1.tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
+        ), 'wrong tagSet'
+
+    def testById(self):
+        self.s1.setComponentByName('name', univ.OctetString('abc'))
+        assert self.s1.getComponentByName('name') == str2octs('abc'), 'set by name fails'
+
+    def testByKey(self):
+        self.s1['name'] = 'abc'
+        assert self.s1['name'] == str2octs('abc'), 'set by key fails'
+
+    def testContains(self):
+        assert 'name' in self.s1
+        assert '<missing>' not in self.s1
+
+    def testGetNearPosition(self):
+        assert self.s1.componentType.getTagMapNearPosition(1).presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString(''),
+            univ.Integer.tagSet: univ.Integer(34)
+        }
+        assert self.s1.componentType.getPositionNearType(
+            univ.OctetString.tagSet, 1
+        ) == 1
+
+    def testSetDefaultComponents(self):
+        self.s1.clear()
+        self.s1.setComponentByPosition(0, univ.OctetString('Ping'))
+        self.s1.setComponentByPosition(1, univ.OctetString('Pong'))
+        assert self.s1.getComponentByPosition(2) == 34
+
+    def testClone(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        self.s1.setComponentByPosition(1, univ.OctetString('def'))
+        self.s1.setComponentByPosition(2, univ.Integer(123))
+        s = self.s1.clone()
+        assert s.getComponentByPosition(0) != self.s1.getComponentByPosition(0)
+        assert s.getComponentByPosition(1) != self.s1.getComponentByPosition(1)
+        assert s.getComponentByPosition(2) != self.s1.getComponentByPosition(2)
+        s = self.s1.clone(cloneValueFlag=1)
+        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+        assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1)
+        assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2)
+
+    def testComponentTagsMatching(self):
+        s = self.s1.clone()
+        s.strictConstraints = True  # This requires types equality
+        o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12))
+        try:
+            s.setComponentByName('name', o)
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'inner supertype tag allowed'
+
+    def testComponentConstraintsMatching(self):
+        s = self.s1.clone()
+        o = univ.OctetString().subtype(
+            subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba'))))
+        s.strictConstraints = True  # This requires types equality
+        try:
+            s.setComponentByName('name', o.clone('cba'))
+        except PyAsn1Error:
+            pass
+        else:
+            assert 0, 'inner supertype constraint allowed'
+        s.strictConstraints = False  # This requires subtype relationships
+        try:
+            s.setComponentByName('name', o.clone('cba'))
+        except PyAsn1Error:
+            assert 0, 'inner supertype constraint disallowed'
+        else:
+            pass
+
+    def testSetComponents(self):
+        assert self.s1.clone().setComponents(name='a', nick='b', age=1) == \
+               self.s1.setComponentByPosition(0, 'a').setComponentByPosition(1, 'b').setComponentByPosition(2, 1)
+
+    def testSetToDefault(self):
+        s = self.s1.clone()
+        s.setComponentByPosition(0, univ.noValue)
+        s[2] = univ.noValue
+        assert s[0] == univ.OctetString('')
+        assert s[2] == univ.Integer(34)
+
+    def testGetItem(self):
+        s = self.s1.clone()
+        s['name'] = 'xxx'
+        assert s['name']
+        assert s[0]
+
+        try:
+            s['xxx']
+
+        except KeyError:
+            pass
+
+        else:
+            assert False, 'KeyError not raised'
+
+        try:
+            s[100]
+
+        except IndexError:
+            pass
+
+        else:
+            assert False, 'IndexError not raised'
+
+    def testSetItem(self):
+        s = self.s1.clone()
+        s['name'] = 'xxx'
+
+        try:
+
+            s['xxx'] = 'xxx'
+
+        except KeyError:
+            pass
+
+        else:
+            assert False, 'KeyError not raised'
+
+        try:
+
+            s[100] = 'xxx'
+
+        except IndexError:
+            pass
+
+        else:
+            assert False, 'IndexError not raised'
+
+    def testIter(self):
+        assert list(self.s1) == ['name', 'nick', 'age']
+
+    def testKeys(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        self.s1.setComponentByPosition(1, univ.OctetString('def'))
+        self.s1.setComponentByPosition(2, univ.Integer(123))
+        assert list(self.s1.keys()) == ['name', 'nick', 'age']
+
+    def testValues(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        self.s1.setComponentByPosition(1, univ.OctetString('def'))
+        self.s1.setComponentByPosition(2, univ.Integer(123))
+        assert list(self.s1.values()) == [str2octs('abc'), str2octs('def'), 123]
+
+    def testItems(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        self.s1.setComponentByPosition(1, univ.OctetString('def'))
+        self.s1.setComponentByPosition(2, univ.Integer(123))
+        assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)]
+
+    def testUpdate(self):
+        self.s1.clear()
+        assert list(self.s1.values()) == [str2octs(''), str2octs(''), 34]
+        self.s1.update(**{'name': 'abc', 'nick': 'def', 'age': 123})
+        assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)]
+        self.s1.update(('name', 'ABC'))
+        assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'ABC'), ('nick', 'def')]] + [('age', 123)]
+        self.s1.update(name='CBA')
+        assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'CBA'), ('nick', 'def')]] + [('age', 123)]
+
+    def testStaticDef(self):
+
+        class Sequence(univ.Sequence):
+            componentType = namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString('')),
+                namedtype.OptionalNamedType('nick', univ.OctetString('')),
+                namedtype.DefaultedNamedType('age', univ.Integer(34))
+            )
+
+        s = Sequence()
+        s['name'] = 'abc'
+        assert s['name'] == str2octs('abc')
+
+
+class SequenceWithoutSchema(BaseTestCase):
+
+    def testGetItem(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s[0] = 'abc'
+        assert s['field-0']
+        assert s[0]
+
+        try:
+            s['field-1']
+
+        except KeyError:
+            pass
+
+        else:
+            assert False, 'KeyError not raised'
+
+    def testSetItem(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s['field-0'] = 'xxx'
+
+        try:
+
+            s['field-1'] = 'xxx'
+
+        except KeyError:
+            pass
+
+        else:
+            assert False, 'KeyError not raised'
+
+    def testIter(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s.setComponentByPosition(1, univ.Integer(123))
+        assert list(s) == ['field-0', 'field-1']
+
+    def testKeys(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s.setComponentByPosition(1, univ.Integer(123))
+        assert list(s.keys()) == ['field-0', 'field-1']
+
+    def testValues(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s.setComponentByPosition(1, univ.Integer(123))
+        assert list(s.values()) == [str2octs('abc'), 123]
+
+    def testItems(self):
+        s = univ.Sequence()
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s.setComponentByPosition(1, univ.Integer(123))
+        assert list(s.items()) == [('field-0', str2octs('abc')), ('field-1', 123)]
+
+    def testUpdate(self):
+        s = univ.Sequence()
+        assert not s
+        s.setComponentByPosition(0, univ.OctetString('abc'))
+        s.setComponentByPosition(1, univ.Integer(123))
+        assert s
+        assert list(s.keys()) == ['field-0', 'field-1']
+        assert list(s.values()) == [str2octs('abc'), 123]
+        assert list(s.items()) == [('field-0', str2octs('abc')), ('field-1', 123)]
+        s['field-0'] = univ.OctetString('def')
+        assert list(s.values()) == [str2octs('def'), 123]
+        s['field-1'] = univ.OctetString('ghi')
+        assert list(s.values()) == [str2octs('def'), str2octs('ghi')]
+        try:
+            s['field-2'] = univ.OctetString('xxx')
+        except KeyError:
+            pass
+        else:
+            assert False, 'unknown field at schema-less object tolerated'
+        assert 'field-0' in s
+        s.clear()
+        assert 'field-0' not in s
+
+
+class SetOf(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.s1 = univ.SetOf(componentType=univ.OctetString(''))
+
+    def testTag(self):
+        assert self.s1.tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+        ), 'wrong tagSet'
+
+    def testSeq(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        assert self.s1[0] == str2octs('abc'), 'set by idx fails'
+        self.s1.setComponentByPosition(0, self.s1[0].clone('cba'))
+        assert self.s1[0] == str2octs('cba'), 'set by idx fails'
+
+    def testStaticDef(self):
+
+        class SetOf(univ.SequenceOf):
+            componentType = univ.OctetString('')
+
+        s = SetOf()
+        s[0] = 'abc'
+        assert len(s) == 1
+        assert s == [str2octs('abc')]
+
+
+class Set(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        self.s1 = univ.Set(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString('')),
+                namedtype.OptionalNamedType('null', univ.Null('')),
+                namedtype.DefaultedNamedType('age', univ.Integer(34))
+            )
+        )
+        self.s2 = self.s1.clone()
+
+    def testTag(self):
+        assert self.s1.tagSet == tag.TagSet(
+            (),
+            tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
+        ), 'wrong tagSet'
+
+    def testByTypeWithPythonValue(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert self.s1.getComponentByType(
+            univ.OctetString.tagSet
+        ) == str2octs('abc'), 'set by name fails'
+
+    def testByTypeWithInstance(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, univ.OctetString('abc'))
+        assert self.s1.getComponentByType(
+            univ.OctetString.tagSet
+        ) == str2octs('abc'), 'set by name fails'
+
+    def testGetTagMap(self):
+        assert self.s1.tagMap.presentTypes == {
+            univ.Set.tagSet: univ.Set()
+        }
+
+    def testGetComponentTagMap(self):
+        assert self.s1.componentType.tagMapUnique.presentTypes == {
+            univ.OctetString.tagSet: univ.OctetString(''),
+            univ.Null.tagSet: univ.Null(''),
+            univ.Integer.tagSet: univ.Integer(34)
+        }
+
+    def testGetPositionByType(self):
+        assert self.s1.componentType.getPositionByType(univ.Null().tagSet) == 1
+
+    def testSetToDefault(self):
+        self.s1.setComponentByName('name', univ.noValue)
+        assert self.s1['name'] == univ.OctetString('')
+
+    def testIter(self):
+        assert list(self.s1) == ['name', 'null', 'age']
+
+    def testStaticDef(self):
+
+        class Set(univ.Set):
+            componentType = namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString('')),
+                namedtype.OptionalNamedType('nick', univ.OctetString('')),
+                namedtype.DefaultedNamedType('age', univ.Integer(34))
+            )
+
+        s = Set()
+        s['name'] = 'abc'
+        assert s['name'] == str2octs('abc')
+
+
+class Choice(BaseTestCase):
+    def setUp(self):
+        BaseTestCase.setUp(self)
+
+        innerComp = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('count', univ.Integer()),
+                namedtype.NamedType('flag', univ.Boolean())
+            )
+        )
+        self.s1 = univ.Choice(
+            componentType=namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString()),
+                namedtype.NamedType('sex', innerComp)
+            )
+        )
+
+    def testTag(self):
+        assert self.s1.tagSet == tag.TagSet(), 'wrong tagSet'
+
+    def testRepr(self):
+        assert eval(repr(self.s1.clone().setComponents('a')),
+                    {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer,
+                     'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes,
+                     'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents('a'), 'repr() fails'
+        assert eval(repr(self.s1.clone().setComponents(
+            sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents(
+                count=univ.Integer(123)))),
+                    {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer,
+                     'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes,
+                     'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents(
+            sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents(
+                count=univ.Integer(123))), 'repr() fails'
+
+    def testContains(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert 'name' in self.s1
+        assert 'sex' not in self.s1
+
+        self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+        assert 'name' not in self.s1
+        assert 'sex' in self.s1
+
+    def testIter(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert list(self.s1) == ['name']
+        self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+        assert list(self.s1) == ['sex']
+
+    def testOuterByTypeWithPythonValue(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert self.s1.getComponentByType(
+            univ.OctetString.tagSet
+        ) == str2octs('abc')
+
+    def testOuterByTypeWithInstanceValue(self):
+        self.s1.setComponentByType(
+            univ.OctetString.tagSet, univ.OctetString('abc')
+        )
+        assert self.s1.getComponentByType(
+            univ.OctetString.tagSet
+        ) == str2octs('abc')
+
+    def testInnerByTypeWithPythonValue(self):
+        self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True)
+        assert self.s1.getComponentByType(
+            univ.Integer.tagSet, 1
+        ) == 123
+
+    def testInnerByTypeWithInstanceValue(self):
+        self.s1.setComponentByType(
+            univ.Integer.tagSet, univ.Integer(123), innerFlag=True
+        )
+        assert self.s1.getComponentByType(
+            univ.Integer.tagSet, 1
+        ) == 123
+
+    def testCmp(self):
+        self.s1.setComponentByName('name', univ.OctetString('abc'))
+        assert self.s1 == str2octs('abc'), '__cmp__() fails'
+
+    def testGetComponent(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert self.s1.getComponent() == str2octs('abc'), 'getComponent() fails'
+
+    def testGetName(self):
+        self.s1.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert self.s1.getName() == 'name', 'getName() fails'
+
+    def testSetComponentByPosition(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('Jim'))
+        assert self.s1 == str2octs('Jim')
+
+    def testClone(self):
+        self.s1.setComponentByPosition(0, univ.OctetString('abc'))
+        s = self.s1.clone()
+        assert len(s) == 0
+        s = self.s1.clone(cloneValueFlag=1)
+        assert len(s) == 1
+        assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0)
+
+    def testSetToDefault(self):
+        s = self.s1.clone()
+        s.setComponentByName('sex', univ.noValue)
+        assert s['sex'] is not univ.noValue
+
+    def testStaticDef(self):
+
+        class InnerChoice(univ.Choice):
+            componentType = namedtype.NamedTypes(
+                namedtype.NamedType('count', univ.Integer()),
+                namedtype.NamedType('flag', univ.Boolean())
+            )
+
+        class OuterChoice(univ.Choice):
+            componentType = namedtype.NamedTypes(
+                namedtype.NamedType('name', univ.OctetString()),
+                namedtype.NamedType('sex', InnerChoice())
+            )
+
+        c = OuterChoice()
+
+        c.setComponentByType(univ.OctetString.tagSet, 'abc')
+        assert c.getName() == 'name'
+
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)
new file mode 100644
--- /dev/null
+++ b/third_party/python/pyasn1/tests/type/test_useful.py
@@ -0,0 +1,104 @@
+#
+# This file is part of pyasn1 software.
+#
+# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
+# License: http://pyasn1.sf.net/license.html
+#
+import sys
+import datetime
+from copy import deepcopy
+
+try:
+    import unittest2 as unittest
+
+except ImportError:
+    import unittest
+
+from tests.base import BaseTestCase
+
+from pyasn1.type import useful
+
+class FixedOffset(datetime.tzinfo):
+    def __init__(self, offset, name):
+        self.__offset = datetime.timedelta(minutes=offset)
+        self.__name = name
+
+    def utcoffset(self, dt):
+        return self.__offset
+
+    def tzname(self, dt):
+        return self.__name
+
+    def dst(self, dt):
+        return datetime.timedelta(0)
+
+
+UTC = FixedOffset(0, 'UTC')
+UTC2 = FixedOffset(120, 'UTC')
+
+
+class ObjectDescriptorTestCase(BaseTestCase):
+    pass
+
+
+class GeneralizedTimeTestCase(BaseTestCase):
+
+    def testFromDateTime(self):
+        assert useful.GeneralizedTime.fromDateTime(datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC)) == '20170711000102.3Z'
+
+    def testToDateTime0(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2) == useful.GeneralizedTime('20170711000102').asDateTime
+
+    def testToDateTime1(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.GeneralizedTime('20170711000102Z').asDateTime
+
+    def testToDateTime2(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102.3Z').asDateTime
+
+    def testToDateTime3(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102,3Z').asDateTime
+
+    def testToDateTime4(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC) == useful.GeneralizedTime('20170711000102.3+0000').asDateTime
+
+    def testToDateTime5(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC2) == useful.GeneralizedTime('20170711000102.3+0200').asDateTime
+
+    def testToDateTime6(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, 30000, tzinfo=UTC2) == useful.GeneralizedTime('20170711000102.3+02').asDateTime
+
+    def testToDateTime7(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1) == useful.GeneralizedTime('201707110001').asDateTime
+
+    def testToDateTime8(self):
+        assert datetime.datetime(2017, 7, 11, 0) == useful.GeneralizedTime('2017071100').asDateTime
+
+    def testCopy(self):
+        dt = useful.GeneralizedTime("20170916234254+0130").asDateTime
+        assert dt == deepcopy(dt)
+
+
+class UTCTimeTestCase(BaseTestCase):
+
+    def testFromDateTime(self):
+        assert useful.UTCTime.fromDateTime(datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC)) == '170711000102Z'
+
+    def testToDateTime0(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2) == useful.UTCTime('170711000102').asDateTime
+
+    def testToDateTime1(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.UTCTime('170711000102Z').asDateTime
+
+    def testToDateTime2(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC) == useful.UTCTime('170711000102+0000').asDateTime
+
+    def testToDateTime3(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1, 2, tzinfo=UTC2) == useful.UTCTime('170711000102+0200').asDateTime
+
+    def testToDateTime4(self):
+        assert datetime.datetime(2017, 7, 11, 0, 1) == useful.UTCTime('1707110001').asDateTime
+
+suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
+
+if __name__ == '__main__':
+    unittest.TextTestRunner(verbosity=2).run(suite)