summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-06-04 16:55:26 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-06-04 16:55:26 +0700
commit3eb93b423abeefbdc03f0ecc38751d76428ba23e (patch)
treef364f857c54f65eb59462560b1f282b896eecf8b
parentPort LinkedCertificate from bc-java (diff)
downloadBouncyCastle.NET-ed25519-3eb93b423abeefbdc03f0ecc38751d76428ba23e.tar.xz
Refactoring
-rw-r--r--crypto/src/asn1/cmp/CertRepMessage.cs8
-rw-r--r--crypto/src/asn1/cmp/CertifiedKeyPair.cs13
-rw-r--r--crypto/src/asn1/cmp/Challenge.cs3
-rw-r--r--crypto/src/asn1/cmp/InfoTypeAndValue.cs7
-rw-r--r--crypto/src/asn1/cmp/KeyRecRepContent.cs14
-rw-r--r--crypto/src/asn1/cmp/OobCertHash.cs13
-rw-r--r--crypto/src/asn1/cmp/PKIHeader.cs28
-rw-r--r--crypto/src/asn1/cmp/PKIMessage.cs14
-rw-r--r--crypto/src/asn1/cmp/PKIStatusInfo.cs12
-rw-r--r--crypto/src/asn1/cmp/RevRepContent.cs13
-rw-r--r--crypto/src/asn1/cms/AuthEnvelopedData.cs27
-rw-r--r--crypto/src/asn1/cms/AuthenticatedData.cs28
-rw-r--r--crypto/src/asn1/cms/EnvelopedData.cs14
-rw-r--r--crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs11
-rw-r--r--crypto/src/asn1/cms/OriginatorInfo.cs13
-rw-r--r--crypto/src/asn1/cms/PasswordRecipientInfo.cs8
-rw-r--r--crypto/src/asn1/cms/SCVPReqRes.cs8
-rw-r--r--crypto/src/asn1/cms/SignerInfo.cs17
-rw-r--r--crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs7
-rw-r--r--crypto/src/asn1/crmf/EncryptedValue.cs21
-rw-r--r--crypto/src/asn1/crmf/OptionalValidity.cs13
-rw-r--r--crypto/src/asn1/crmf/PopoSigningKey.cs8
-rw-r--r--crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs10
-rw-r--r--crypto/src/asn1/esf/CommitmentTypeIndication.cs7
-rw-r--r--crypto/src/asn1/esf/CommitmentTypeQualifier.cs10
-rw-r--r--crypto/src/asn1/esf/CrlIdentifier.cs10
-rw-r--r--crypto/src/asn1/esf/OtherSigningCertificate.cs7
-rw-r--r--crypto/src/asn1/esf/RevocationValues.cs16
-rw-r--r--crypto/src/asn1/esf/SignerLocation.cs19
-rw-r--r--crypto/src/asn1/ess/ContentHints.cs8
-rw-r--r--crypto/src/asn1/ess/ESSCertID.cs7
-rw-r--r--crypto/src/asn1/ess/ESSCertIDv2.cs7
-rw-r--r--crypto/src/asn1/ess/OtherCertID.cs7
-rw-r--r--crypto/src/asn1/ess/OtherSigningCertificate.cs7
-rw-r--r--crypto/src/asn1/ess/SigningCertificate.cs7
-rw-r--r--crypto/src/asn1/ess/SigningCertificateV2.cs7
-rw-r--r--crypto/src/asn1/icao/LDSSecurityObject.cs7
-rw-r--r--crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs11
-rw-r--r--crypto/src/asn1/isismtt/x509/Admissions.cs20
-rw-r--r--crypto/src/asn1/isismtt/x509/NamingAuthority.cs18
-rw-r--r--crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs36
-rw-r--r--crypto/src/asn1/isismtt/x509/ProfessionInfo.cs37
-rw-r--r--crypto/src/asn1/misc/IDEACBCPar.cs9
-rw-r--r--crypto/src/asn1/ocsp/BasicOCSPResponse.cs12
-rw-r--r--crypto/src/asn1/ocsp/CrlID.cs21
-rw-r--r--crypto/src/asn1/ocsp/OCSPRequest.cs9
-rw-r--r--crypto/src/asn1/ocsp/OCSPResponse.cs9
-rw-r--r--crypto/src/asn1/ocsp/Request.cs9
-rw-r--r--crypto/src/asn1/ocsp/ResponseData.cs15
-rw-r--r--crypto/src/asn1/ocsp/RevokedInfo.cs11
-rw-r--r--crypto/src/asn1/ocsp/ServiceLocator.cs9
-rw-r--r--crypto/src/asn1/ocsp/Signature.cs12
-rw-r--r--crypto/src/asn1/ocsp/SingleResponse.cs18
-rw-r--r--crypto/src/asn1/ocsp/TBSRequest.cs29
-rw-r--r--crypto/src/asn1/pkcs/CertificationRequestInfo.cs14
-rw-r--r--crypto/src/asn1/pkcs/DHParameter.cs11
-rw-r--r--crypto/src/asn1/pkcs/PBKDF2Params.cs8
-rw-r--r--crypto/src/asn1/pkcs/Pfx.cs14
-rw-r--r--crypto/src/asn1/pkcs/PrivateKeyInfo.cs13
-rw-r--r--crypto/src/asn1/pkcs/RC2CBCParameter.cs14
-rw-r--r--crypto/src/asn1/pkcs/SafeBag.cs14
-rw-r--r--crypto/src/asn1/pkcs/SignedData.cs17
-rw-r--r--crypto/src/asn1/pkcs/SignerInfo.cs21
-rw-r--r--crypto/src/asn1/smime/SMIMECapability.cs9
-rw-r--r--crypto/src/asn1/tsp/Accuracy.cs29
-rw-r--r--crypto/src/asn1/tsp/TSTInfo.cs47
-rw-r--r--crypto/src/asn1/tsp/TimeStampReq.cs40
-rw-r--r--crypto/src/asn1/tsp/TimeStampResp.cs17
-rw-r--r--crypto/src/asn1/x509/AttributeCertificateInfo.cs19
-rw-r--r--crypto/src/asn1/x509/AuthorityKeyIdentifier.cs21
-rw-r--r--crypto/src/asn1/x509/BasicConstraints.cs15
-rw-r--r--crypto/src/asn1/x509/CertificatePair.cs23
-rw-r--r--crypto/src/asn1/x509/DistributionPoint.cs25
-rw-r--r--crypto/src/asn1/x509/GeneralSubtree.cs6
-rw-r--r--crypto/src/asn1/x509/Holder.cs45
-rw-r--r--crypto/src/asn1/x509/IetfAttrSyntax.cs12
-rw-r--r--crypto/src/asn1/x509/IssuerSerial.cs18
-rw-r--r--crypto/src/asn1/x509/NameConstraints.cs23
-rw-r--r--crypto/src/asn1/x509/ObjectDigestInfo.cs14
-rw-r--r--crypto/src/asn1/x509/PolicyInformation.cs9
-rw-r--r--crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs23
-rw-r--r--crypto/src/asn1/x509/RoleSyntax.cs20
-rw-r--r--crypto/src/asn1/x509/UserNotice.cs16
-rw-r--r--crypto/src/asn1/x509/V2Form.cs19
-rw-r--r--crypto/src/asn1/x509/qualified/BiometricData.cs14
-rw-r--r--crypto/src/asn1/x509/qualified/QCStatement.cs13
-rw-r--r--crypto/src/asn1/x509/qualified/SemanticsInformation.cs16
-rw-r--r--crypto/src/asn1/x509/sigi/PersonalData.cs46
-rw-r--r--crypto/src/asn1/x9/DHDomainParameters.cs22
-rw-r--r--crypto/src/asn1/x9/OtherInfo.cs12
90 files changed, 371 insertions, 1049 deletions
diff --git a/crypto/src/asn1/cmp/CertRepMessage.cs b/crypto/src/asn1/cmp/CertRepMessage.cs
index 82869784d..d24dd963b 100644
--- a/crypto/src/asn1/cmp/CertRepMessage.cs
+++ b/crypto/src/asn1/cmp/CertRepMessage.cs
@@ -82,14 +82,8 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (caPubs != null)
-			{
-				v.Add(new DerTaggedObject(true, 1, caPubs));
-			}
-
+            v.AddOptionalTagged(true, 1, caPubs);
 			v.Add(response);
-
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/cmp/CertifiedKeyPair.cs b/crypto/src/asn1/cmp/CertifiedKeyPair.cs
index c06f00019..0b1c5d44d 100644
--- a/crypto/src/asn1/cmp/CertifiedKeyPair.cs
+++ b/crypto/src/asn1/cmp/CertifiedKeyPair.cs
@@ -98,17 +98,8 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(certOrEncCert);
-
-			if (privateKey != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, privateKey));
-			}
-
-			if (publicationInfo != null)
-			{
-				v.Add(new DerTaggedObject(true, 1, publicationInfo));
-			}
-
+            v.AddOptionalTagged(true, 0, privateKey);
+            v.AddOptionalTagged(true, 1, publicationInfo);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/cmp/Challenge.cs b/crypto/src/asn1/cmp/Challenge.cs
index 5c78c2a2b..016c082e2 100644
--- a/crypto/src/asn1/cmp/Challenge.cs
+++ b/crypto/src/asn1/cmp/Challenge.cs
@@ -72,8 +72,7 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
 			v.AddOptional(owf);
-			v.Add(witness);
-			v.Add(challenge);
+			v.Add(witness, challenge);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/cmp/InfoTypeAndValue.cs b/crypto/src/asn1/cmp/InfoTypeAndValue.cs
index 0ce6f73ba..305d6e5e7 100644
--- a/crypto/src/asn1/cmp/InfoTypeAndValue.cs
+++ b/crypto/src/asn1/cmp/InfoTypeAndValue.cs
@@ -111,12 +111,7 @@ namespace Org.BouncyCastle.Asn1.Cmp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(infoType);
-
-            if (infoValue != null)
-            {
-                v.Add(infoValue);
-            }
-
+            v.AddOptional(infoValue);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cmp/KeyRecRepContent.cs b/crypto/src/asn1/cmp/KeyRecRepContent.cs
index 00c4612b9..e35c0e351 100644
--- a/crypto/src/asn1/cmp/KeyRecRepContent.cs
+++ b/crypto/src/asn1/cmp/KeyRecRepContent.cs
@@ -100,18 +100,10 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(status);
-			AddOptional(v, 0, newSigCert);
-			AddOptional(v, 1, caCerts);
-			AddOptional(v, 2, keyPairHist);
+            v.AddOptionalTagged(true, 0, newSigCert);
+            v.AddOptionalTagged(true, 1, caCerts);
+            v.AddOptionalTagged(true, 2, keyPairHist);
 			return new DerSequence(v);
 		}
-
-		private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-		{
-			if (obj != null)
-			{
-				v.Add(new DerTaggedObject(true, tagNo, obj));
-			}
-		}
 	}
 }
diff --git a/crypto/src/asn1/cmp/OobCertHash.cs b/crypto/src/asn1/cmp/OobCertHash.cs
index cd8192b40..434939c0e 100644
--- a/crypto/src/asn1/cmp/OobCertHash.cs
+++ b/crypto/src/asn1/cmp/OobCertHash.cs
@@ -70,19 +70,10 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
-			AddOptional(v, 0, hashAlg);
-			AddOptional(v, 1, certId);
+            v.AddOptionalTagged(true, 0, hashAlg);
+            v.AddOptionalTagged(true, 1, certId);
 			v.Add(hashVal);
 			return new DerSequence(v);
 		}
-
-		private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-		{
-			if (obj != null)
-			{
-				v.Add(new DerTaggedObject(true, tagNo, obj));
-			}
-		}
 	}
 }
-
diff --git a/crypto/src/asn1/cmp/PKIHeader.cs b/crypto/src/asn1/cmp/PKIHeader.cs
index 577cb45df..7b6296279 100644
--- a/crypto/src/asn1/cmp/PKIHeader.cs
+++ b/crypto/src/asn1/cmp/PKIHeader.cs
@@ -213,26 +213,16 @@ namespace Org.BouncyCastle.Asn1.Cmp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(pvno, sender, recipient);
-
-            AddOptional(v, 0, messageTime);
-            AddOptional(v, 1, protectionAlg);
-            AddOptional(v, 2, senderKID);
-            AddOptional(v, 3, recipKID);
-            AddOptional(v, 4, transactionID);
-            AddOptional(v, 5, senderNonce);
-            AddOptional(v, 6, recipNonce);
-            AddOptional(v, 7, freeText);
-            AddOptional(v, 8, generalInfo);
-
+            v.AddOptionalTagged(true, 0, messageTime);
+            v.AddOptionalTagged(true, 1, protectionAlg);
+            v.AddOptionalTagged(true, 2, senderKID);
+            v.AddOptionalTagged(true, 3, recipKID);
+            v.AddOptionalTagged(true, 4, transactionID);
+            v.AddOptionalTagged(true, 5, senderNonce);
+            v.AddOptionalTagged(true, 6, recipNonce);
+            v.AddOptionalTagged(true, 7, freeText);
+            v.AddOptionalTagged(true, 8, generalInfo);
             return new DerSequence(v);
         }
-
-        private static void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-        {
-            if (obj != null)
-            {
-                v.Add(new DerTaggedObject(true, tagNo, obj));
-            }
-        }
     }
 }
diff --git a/crypto/src/asn1/cmp/PKIMessage.cs b/crypto/src/asn1/cmp/PKIMessage.cs
index 086a2d938..c87bf2126 100644
--- a/crypto/src/asn1/cmp/PKIMessage.cs
+++ b/crypto/src/asn1/cmp/PKIMessage.cs
@@ -122,19 +122,9 @@ namespace Org.BouncyCastle.Asn1.Cmp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(header, body);
-
-            AddOptional(v, 0, protection);
-            AddOptional(v, 1, extraCerts);
-
+            v.AddOptionalTagged(true, 0, protection);
+            v.AddOptionalTagged(true, 1, extraCerts);
             return new DerSequence(v);
         }
-
-        private static void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-        {
-            if (obj != null)
-            {
-                v.Add(new DerTaggedObject(true, tagNo, obj));
-            }
-        }
     }
 }
diff --git a/crypto/src/asn1/cmp/PKIStatusInfo.cs b/crypto/src/asn1/cmp/PKIStatusInfo.cs
index b19bf7459..c9f64bfde 100644
--- a/crypto/src/asn1/cmp/PKIStatusInfo.cs
+++ b/crypto/src/asn1/cmp/PKIStatusInfo.cs
@@ -149,17 +149,7 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(status);
-
-			if (statusString != null)
-			{
-				v.Add(statusString);
-			}
-
-			if (failInfo!= null)
-			{
-				v.Add(failInfo);
-			}
-
+            v.AddOptional(statusString, failInfo);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/cmp/RevRepContent.cs b/crypto/src/asn1/cmp/RevRepContent.cs
index 8e382a60d..4b3f82b96 100644
--- a/crypto/src/asn1/cmp/RevRepContent.cs
+++ b/crypto/src/asn1/cmp/RevRepContent.cs
@@ -96,18 +96,9 @@ namespace Org.BouncyCastle.Asn1.Cmp
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(status);
-			AddOptional(v, 0, revCerts);
-			AddOptional(v, 1, crls);
+            v.AddOptionalTagged(true, 0, revCerts);
+            v.AddOptionalTagged(true, 1, crls);
 			return new DerSequence(v);
 		}
-
-		private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-		{
-			if (obj != null)
-			{
-				v.Add(new DerTaggedObject(true, tagNo, obj));
-			}
-		}
 	}
 }
-
diff --git a/crypto/src/asn1/cms/AuthEnvelopedData.cs b/crypto/src/asn1/cms/AuthEnvelopedData.cs
index c30ec6bbd..6277e4b87 100644
--- a/crypto/src/asn1/cms/AuthEnvelopedData.cs
+++ b/crypto/src/asn1/cms/AuthEnvelopedData.cs
@@ -175,31 +175,20 @@ namespace Org.BouncyCastle.Asn1.Cms
 	    public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(version);
-
-			if (originatorInfo != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, originatorInfo));
-			}
-
+            v.AddOptionalTagged(false, 0, originatorInfo);
 			v.Add(recipientInfos, authEncryptedContentInfo);
 
 			// "authAttrs optionally contains the authenticated attributes."
-			if (authAttrs != null)
-			{
-				// "AuthAttributes MUST be DER encoded, even if the rest of the
-				// AuthEnvelopedData structure is BER encoded."
-				v.Add(new DerTaggedObject(false, 1, authAttrs));
-			}
+            // "AuthAttributes MUST be DER encoded, even if the rest of the
+            // AuthEnvelopedData structure is BER encoded."
+            v.AddOptionalTagged(false, 1, authAttrs);
 
-			v.Add(mac);
+            v.Add(mac);
 
-			// "unauthAttrs optionally contains the unauthenticated attributes."
-			if (unauthAttrs != null)
-			{
-				v.Add(new DerTaggedObject(false, 2, unauthAttrs));
-			}
+            // "unauthAttrs optionally contains the unauthenticated attributes."
+            v.AddOptionalTagged(false, 2, unauthAttrs);
 
-			return new BerSequence(v);
+            return new BerSequence(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/cms/AuthenticatedData.cs b/crypto/src/asn1/cms/AuthenticatedData.cs
index 6f13a6f30..eb9f82031 100644
--- a/crypto/src/asn1/cms/AuthenticatedData.cs
+++ b/crypto/src/asn1/cms/AuthenticatedData.cs
@@ -196,33 +196,13 @@ namespace Org.BouncyCastle.Asn1.Cms
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(version);
-
-			if (originatorInfo != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, originatorInfo));
-			}
-
+            v.AddOptionalTagged(false, 0, originatorInfo);
 			v.Add(recipientInfos, macAlgorithm);
-
-			if (digestAlgorithm != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, digestAlgorithm));
-			}
-
+            v.AddOptionalTagged(false, 1, digestAlgorithm);
 			v.Add(encapsulatedContentInfo);
-
-			if (authAttrs != null)
-			{
-				v.Add(new DerTaggedObject(false, 2, authAttrs));
-			}
-
+            v.AddOptionalTagged(false, 2, authAttrs);
 			v.Add(mac);
-
-			if (unauthAttrs != null)
-			{
-				v.Add(new DerTaggedObject(false, 3, unauthAttrs));
-			}
-
+            v.AddOptionalTagged(false, 3, unauthAttrs);
 			return new BerSequence(v);
 		}
 
diff --git a/crypto/src/asn1/cms/EnvelopedData.cs b/crypto/src/asn1/cms/EnvelopedData.cs
index 09f291a93..41dae548f 100644
--- a/crypto/src/asn1/cms/EnvelopedData.cs
+++ b/crypto/src/asn1/cms/EnvelopedData.cs
@@ -137,19 +137,9 @@ namespace Org.BouncyCastle.Asn1.Cms
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(version);
-
-            if (originatorInfo != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, originatorInfo));
-            }
-
+            v.AddOptionalTagged(false, 0, originatorInfo);
             v.Add(recipientInfos, encryptedContentInfo);
-
-            if (unprotectedAttrs != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, unprotectedAttrs));
-            }
-
+            v.AddOptionalTagged(false, 1, unprotectedAttrs);
             return new BerSequence(v);
         }
 
diff --git a/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs b/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
index 62a38925b..52eb7d4d3 100644
--- a/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
+++ b/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
@@ -125,16 +125,9 @@ namespace Org.BouncyCastle.Asn1.Cms
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				version, new DerTaggedObject(true, 0, originator));
-
-			if (ukm != null)
-            {
-                v.Add(new DerTaggedObject(true, 1, ukm));
-            }
-
+            Asn1EncodableVector v = new Asn1EncodableVector(version, new DerTaggedObject(true, 0, originator));
+            v.AddOptionalTagged(true, 1, ukm);
 			v.Add(keyEncryptionAlgorithm, recipientEncryptedKeys);
-
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cms/OriginatorInfo.cs b/crypto/src/asn1/cms/OriginatorInfo.cs
index 33b049efa..23acc2d9f 100644
--- a/crypto/src/asn1/cms/OriginatorInfo.cs
+++ b/crypto/src/asn1/cms/OriginatorInfo.cs
@@ -104,17 +104,8 @@ namespace Org.BouncyCastle.Asn1.Cms
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (certs != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, certs));
-            }
-
-			if (crls != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, crls));
-            }
-
+            v.AddOptionalTagged(false, 0, certs);
+            v.AddOptionalTagged(false, 1, crls);
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cms/PasswordRecipientInfo.cs b/crypto/src/asn1/cms/PasswordRecipientInfo.cs
index 7f275fde7..596dd9537 100644
--- a/crypto/src/asn1/cms/PasswordRecipientInfo.cs
+++ b/crypto/src/asn1/cms/PasswordRecipientInfo.cs
@@ -119,14 +119,8 @@ namespace Org.BouncyCastle.Asn1.Cms
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(version);
-
-			if (keyDerivationAlgorithm != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, keyDerivationAlgorithm));
-            }
-
+            v.AddOptionalTagged(false, 0, keyDerivationAlgorithm);
 			v.Add(keyEncryptionAlgorithm, encryptedKey);
-
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cms/SCVPReqRes.cs b/crypto/src/asn1/cms/SCVPReqRes.cs
index 486979a29..a6ebf7302 100644
--- a/crypto/src/asn1/cms/SCVPReqRes.cs
+++ b/crypto/src/asn1/cms/SCVPReqRes.cs
@@ -63,14 +63,8 @@ namespace Org.BouncyCastle.Asn1.Cms
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-            if (request != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, request));
-            }
-
+            v.AddOptionalTagged(true, 0, request);
             v.Add(response);
-
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cms/SignerInfo.cs b/crypto/src/asn1/cms/SignerInfo.cs
index b6bd319b0..44d4dcfb2 100644
--- a/crypto/src/asn1/cms/SignerInfo.cs
+++ b/crypto/src/asn1/cms/SignerInfo.cs
@@ -164,21 +164,10 @@ namespace Org.BouncyCastle.Asn1.Cms
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-                version, sid, digAlgorithm);
-
-            if (authenticatedAttributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, authenticatedAttributes));
-            }
-
+            Asn1EncodableVector v = new Asn1EncodableVector(version, sid, digAlgorithm);
+            v.AddOptionalTagged(false, 0, authenticatedAttributes);
             v.Add(digEncryptionAlgorithm, encryptedDigest);
-
-            if (unauthenticatedAttributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes));
-            }
-
+            v.AddOptionalTagged(false, 1, unauthenticatedAttributes);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs b/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
index dc4ac1a4a..3a4761e78 100644
--- a/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
+++ b/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
@@ -93,12 +93,7 @@ namespace Org.BouncyCastle.Asn1.Cms.Ecc
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(ephemeralPublicKey);
-
-			if (addedukm != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, addedukm));
-			}
-
+            v.AddOptionalTagged(true, 0, addedukm);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/crmf/EncryptedValue.cs b/crypto/src/asn1/crmf/EncryptedValue.cs
index 83122e220..7c5cf18b4 100644
--- a/crypto/src/asn1/crmf/EncryptedValue.cs
+++ b/crypto/src/asn1/crmf/EncryptedValue.cs
@@ -131,24 +131,13 @@ namespace Org.BouncyCastle.Asn1.Crmf
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-            AddOptional(v, 0, intendedAlg);
-            AddOptional(v, 1, symmAlg);
-            AddOptional(v, 2, encSymmKey);
-            AddOptional(v, 3, keyAlg);
-            AddOptional(v, 4, valueHint);
-
+            v.AddOptionalTagged(false, 0, intendedAlg);
+            v.AddOptionalTagged(false, 1, symmAlg);
+            v.AddOptionalTagged(false, 2, encSymmKey);
+            v.AddOptionalTagged(false, 3, keyAlg);
+            v.AddOptionalTagged(false, 4, valueHint);
             v.Add(encValue);
-
             return new DerSequence(v);
         }
-
-        private void AddOptional(Asn1EncodableVector v, int tagNo, Asn1Encodable obj)
-        {
-            if (obj != null)
-            {
-                v.Add(new DerTaggedObject(false, tagNo, obj));
-            }
-        }
     }
 }
diff --git a/crypto/src/asn1/crmf/OptionalValidity.cs b/crypto/src/asn1/crmf/OptionalValidity.cs
index 46fd1f860..d608ea5d1 100644
--- a/crypto/src/asn1/crmf/OptionalValidity.cs
+++ b/crypto/src/asn1/crmf/OptionalValidity.cs
@@ -60,17 +60,8 @@ namespace Org.BouncyCastle.Asn1.Crmf
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-            if (notBefore != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, notBefore));
-            }
-
-            if (notAfter != null)
-            {
-                v.Add(new DerTaggedObject(true, 1, notAfter));
-            }
-
+            v.AddOptionalTagged(true, 0, notBefore);
+            v.AddOptionalTagged(true, 1, notAfter);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/crmf/PopoSigningKey.cs b/crypto/src/asn1/crmf/PopoSigningKey.cs
index 1c24db8ee..11e735415 100644
--- a/crypto/src/asn1/crmf/PopoSigningKey.cs
+++ b/crypto/src/asn1/crmf/PopoSigningKey.cs
@@ -101,15 +101,9 @@ namespace Org.BouncyCastle.Asn1.Crmf
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-            if (poposkInput != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, poposkInput));
-            }
-
+            v.AddOptionalTagged(false, 0, poposkInput);
             v.Add(algorithmIdentifier);
             v.Add(signature);
-
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs b/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
index ea42a1ec4..32a8fb226 100644
--- a/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
+++ b/crypto/src/asn1/cryptopro/GOST3410PublicKeyAlgParameters.cs
@@ -78,14 +78,8 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
 
 		public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				publicKeyParamSet, digestParamSet);
-
-			if (encryptionParamSet != null)
-            {
-                v.Add(encryptionParamSet);
-            }
-
+            Asn1EncodableVector v = new Asn1EncodableVector(publicKeyParamSet, digestParamSet);
+            v.AddOptional(encryptionParamSet);
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/esf/CommitmentTypeIndication.cs b/crypto/src/asn1/esf/CommitmentTypeIndication.cs
index 196a613a6..ecdb10067 100644
--- a/crypto/src/asn1/esf/CommitmentTypeIndication.cs
+++ b/crypto/src/asn1/esf/CommitmentTypeIndication.cs
@@ -83,12 +83,7 @@ namespace Org.BouncyCastle.Asn1.Esf
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeId);
-
-			if (commitmentTypeQualifier != null)
-            {
-                v.Add(commitmentTypeQualifier);
-            }
-
+            v.AddOptional(commitmentTypeQualifier);
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/esf/CommitmentTypeQualifier.cs b/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
index 30bf0edfc..acf19f9f6 100644
--- a/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
+++ b/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
@@ -105,14 +105,8 @@ namespace Org.BouncyCastle.Asn1.Esf
         */
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				commitmentTypeIdentifier);
-
-			if (qualifier != null)
-			{
-				v.Add(qualifier);
-			}
-
+			Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeIdentifier);
+            v.AddOptional(qualifier);
 			return new DerSequence(v);
 		}
     }
diff --git a/crypto/src/asn1/esf/CrlIdentifier.cs b/crypto/src/asn1/esf/CrlIdentifier.cs
index 96b50e211..a8e40c870 100644
--- a/crypto/src/asn1/esf/CrlIdentifier.cs
+++ b/crypto/src/asn1/esf/CrlIdentifier.cs
@@ -97,14 +97,8 @@ namespace Org.BouncyCastle.Asn1.Esf
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				crlIssuer.ToAsn1Object(), crlIssuedTime);
-
-			if (crlNumber != null)
-			{
-				v.Add(crlNumber);
-			}
-
+			Asn1EncodableVector v = new Asn1EncodableVector(crlIssuer.ToAsn1Object(), crlIssuedTime);
+            v.AddOptional(crlNumber);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/esf/OtherSigningCertificate.cs b/crypto/src/asn1/esf/OtherSigningCertificate.cs
index f7b9f5e66..2b6d646bc 100644
--- a/crypto/src/asn1/esf/OtherSigningCertificate.cs
+++ b/crypto/src/asn1/esf/OtherSigningCertificate.cs
@@ -127,12 +127,7 @@ namespace Org.BouncyCastle.Asn1.Esf
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(certs);
-
-			if (policies != null)
-			{
-				v.Add(policies);
-			}
-
+            v.AddOptional(policies);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/esf/RevocationValues.cs b/crypto/src/asn1/esf/RevocationValues.cs
index a7b47b47a..5be080f05 100644
--- a/crypto/src/asn1/esf/RevocationValues.cs
+++ b/crypto/src/asn1/esf/RevocationValues.cs
@@ -143,23 +143,15 @@ namespace Org.BouncyCastle.Asn1.Esf
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(true, 0, crlVals);
+            v.AddOptionalTagged(true, 1, ocspVals);
 
-			if (crlVals != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, crlVals));
-			}
-
-			if (ocspVals != null)
-			{
-				v.Add(new DerTaggedObject(true, 1, ocspVals));
-			}
-
-			if (otherRevVals != null)
+            if (otherRevVals != null)
 			{
 				v.Add(new DerTaggedObject(true, 2, otherRevVals.ToAsn1Object()));
 			}
 
-			return new DerSequence(v);
+            return new DerSequence(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/esf/SignerLocation.cs b/crypto/src/asn1/esf/SignerLocation.cs
index 16dbcd01f..0095c0e5c 100644
--- a/crypto/src/asn1/esf/SignerLocation.cs
+++ b/crypto/src/asn1/esf/SignerLocation.cs
@@ -150,22 +150,9 @@ namespace Org.BouncyCastle.Asn1.Esf
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (countryName != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, countryName));
-			}
-
-			if (localityName != null)
-			{
-				v.Add(new DerTaggedObject(true, 1, localityName));
-			}
-
-			if (postalAddress != null)
-			{
-				v.Add(new DerTaggedObject(true, 2, postalAddress));
-			}
-
+            v.AddOptionalTagged(true, 0, countryName);
+            v.AddOptionalTagged(true, 1, localityName);
+            v.AddOptionalTagged(true, 2, postalAddress);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/ContentHints.cs b/crypto/src/asn1/ess/ContentHints.cs
index cfd174b3a..81ba0a1fe 100644
--- a/crypto/src/asn1/ess/ContentHints.cs
+++ b/crypto/src/asn1/ess/ContentHints.cs
@@ -80,14 +80,8 @@ namespace Org.BouncyCastle.Asn1.Ess
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (contentDescription != null)
-			{
-				v.Add(contentDescription);
-			}
-
+            v.AddOptional(contentDescription);
 			v.Add(contentType);
-
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/ESSCertID.cs b/crypto/src/asn1/ess/ESSCertID.cs
index b4465ea4f..7e5fe4c1e 100644
--- a/crypto/src/asn1/ess/ESSCertID.cs
+++ b/crypto/src/asn1/ess/ESSCertID.cs
@@ -82,12 +82,7 @@ namespace Org.BouncyCastle.Asn1.Ess
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(certHash);
-
-			if (issuerSerial != null)
-			{
-				v.Add(issuerSerial);
-			}
-
+            v.AddOptional(issuerSerial);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/ESSCertIDv2.cs b/crypto/src/asn1/ess/ESSCertIDv2.cs
index 35ce699e8..1711a769c 100644
--- a/crypto/src/asn1/ess/ESSCertIDv2.cs
+++ b/crypto/src/asn1/ess/ESSCertIDv2.cs
@@ -133,12 +133,7 @@ namespace Org.BouncyCastle.Asn1.Ess
             }
 
             v.Add(new DerOctetString(certHash).ToAsn1Object());
-
-            if (issuerSerial != null)
-            {
-                v.Add(issuerSerial);
-            }
-
+            v.AddOptional(issuerSerial);
             return new DerSequence(v);
         }
 
diff --git a/crypto/src/asn1/ess/OtherCertID.cs b/crypto/src/asn1/ess/OtherCertID.cs
index 7794c81fa..183055e56 100644
--- a/crypto/src/asn1/ess/OtherCertID.cs
+++ b/crypto/src/asn1/ess/OtherCertID.cs
@@ -122,12 +122,7 @@ namespace Org.BouncyCastle.Asn1.Ess
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(otherCertHash);
-
-			if (issuerSerial != null)
-			{
-				v.Add(issuerSerial);
-			}
-
+            v.AddOptional(issuerSerial);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/OtherSigningCertificate.cs b/crypto/src/asn1/ess/OtherSigningCertificate.cs
index 6cef92b62..65152b675 100644
--- a/crypto/src/asn1/ess/OtherSigningCertificate.cs
+++ b/crypto/src/asn1/ess/OtherSigningCertificate.cs
@@ -98,12 +98,7 @@ namespace Org.BouncyCastle.Asn1.Ess
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(certs);
-
-			if (policies != null)
-			{
-				v.Add(policies);
-			}
-
+            v.AddOptional(policies);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/SigningCertificate.cs b/crypto/src/asn1/ess/SigningCertificate.cs
index 51f67c1ff..6b8deee8b 100644
--- a/crypto/src/asn1/ess/SigningCertificate.cs
+++ b/crypto/src/asn1/ess/SigningCertificate.cs
@@ -97,12 +97,7 @@ namespace Org.BouncyCastle.Asn1.Ess
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(certs);
-
-			if (policies != null)
-			{
-				v.Add(policies);
-			}
-
+            v.AddOptional(policies);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/ess/SigningCertificateV2.cs b/crypto/src/asn1/ess/SigningCertificateV2.cs
index 91eda9e33..4694098dd 100644
--- a/crypto/src/asn1/ess/SigningCertificateV2.cs
+++ b/crypto/src/asn1/ess/SigningCertificateV2.cs
@@ -101,12 +101,7 @@ namespace Org.BouncyCastle.Asn1.Ess
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(certs);
-
-            if (policies != null)
-            {
-                v.Add(policies);
-            }
-
+            v.AddOptional(policies);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/icao/LDSSecurityObject.cs b/crypto/src/asn1/icao/LDSSecurityObject.cs
index c33ca6877..cda4aaa37 100644
--- a/crypto/src/asn1/icao/LDSSecurityObject.cs
+++ b/crypto/src/asn1/icao/LDSSecurityObject.cs
@@ -133,12 +133,7 @@ namespace Org.BouncyCastle.Asn1.Icao
 			DerSequence hashSeq = new DerSequence(datagroupHash);
 
 			Asn1EncodableVector v = new Asn1EncodableVector(version, digestAlgorithmIdentifier, hashSeq);
-
-			if (versionInfo != null)
-			{
-				v.Add(versionInfo);
-			}
-
+            v.AddOptional(versionInfo);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs b/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
index 4b6264ae0..a45075ee4 100644
--- a/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
+++ b/crypto/src/asn1/isismtt/x509/AdmissionSyntax.cs
@@ -243,13 +243,10 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509
         */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector vec = new Asn1EncodableVector();
-            if (admissionAuthority != null)
-            {
-                vec.Add(admissionAuthority);
-            }
-            vec.Add(contentsOfAdmissions);
-            return new DerSequence(vec);
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptional(admissionAuthority);
+            v.Add(contentsOfAdmissions);
+            return new DerSequence(v);
         }
 
         /**
diff --git a/crypto/src/asn1/isismtt/x509/Admissions.cs b/crypto/src/asn1/isismtt/x509/Admissions.cs
index e914db0b5..2aa6764bb 100644
--- a/crypto/src/asn1/isismtt/x509/Admissions.cs
+++ b/crypto/src/asn1/isismtt/x509/Admissions.cs
@@ -167,21 +167,11 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509
 		*/
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-
-			if (admissionAuthority != null)
-			{
-				vec.Add(new DerTaggedObject(true, 0, admissionAuthority));
-			}
-
-			if (namingAuthority != null)
-			{
-				vec.Add(new DerTaggedObject(true, 1, namingAuthority));
-			}
-
-			vec.Add(professionInfos);
-
-			return new DerSequence(vec);
+			Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(true, 0, admissionAuthority);
+            v.AddOptionalTagged(true, 1, namingAuthority);
+			v.Add(professionInfos);
+			return new DerSequence(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/isismtt/x509/NamingAuthority.cs b/crypto/src/asn1/isismtt/x509/NamingAuthority.cs
index 35539f488..543dcecc7 100644
--- a/crypto/src/asn1/isismtt/x509/NamingAuthority.cs
+++ b/crypto/src/asn1/isismtt/x509/NamingAuthority.cs
@@ -196,20 +196,16 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509
 		*/
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-			if (namingAuthorityID != null)
-			{
-				vec.Add(namingAuthorityID);
-			}
+			Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptional(namingAuthorityID);
+
 			if (namingAuthorityUrl != null)
 			{
-				vec.Add(new DerIA5String(namingAuthorityUrl, true));
+				v.Add(new DerIA5String(namingAuthorityUrl, true));
 			}
-			if (namingAuthorityText != null)
-			{
-				vec.Add(namingAuthorityText);
-			}
-			return new DerSequence(vec);
+
+            v.AddOptional(namingAuthorityText);
+			return new DerSequence(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs b/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs
index f42364699..60d3a88e8 100644
--- a/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs
+++ b/crypto/src/asn1/isismtt/x509/ProcurationSyntax.cs
@@ -209,25 +209,25 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509
 		*/
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-			if (country != null)
-			{
-				vec.Add(new DerTaggedObject(true, 1, new DerPrintableString(country, true)));
-			}
-			if (typeOfSubstitution != null)
-			{
-				vec.Add(new DerTaggedObject(true, 2, typeOfSubstitution));
-			}
-			if (thirdPerson != null)
-			{
-				vec.Add(new DerTaggedObject(true, 3, thirdPerson));
-			}
-			else
-			{
-				vec.Add(new DerTaggedObject(true, 3, certRef));
-			}
+            Asn1EncodableVector v = new Asn1EncodableVector();
+
+            if (country != null)
+            {
+                v.Add(new DerTaggedObject(true, 1, new DerPrintableString(country, true)));
+            }
+
+            v.AddOptionalTagged(true, 2, typeOfSubstitution);
+
+            if (thirdPerson != null)
+            {
+                v.Add(new DerTaggedObject(true, 3, thirdPerson));
+            }
+            else
+            {
+                v.Add(new DerTaggedObject(true, 3, certRef));
+            }
 
-			return new DerSequence(vec);
+            return new DerSequence(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs b/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs
index 671a465af..b65757c09 100644
--- a/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs
+++ b/crypto/src/asn1/isismtt/x509/ProfessionInfo.cs
@@ -302,28 +302,21 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509
 		*
 		* @return an Asn1Object
 		*/
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-			if (namingAuthority != null)
-			{
-				vec.Add(new DerTaggedObject(true, 0, namingAuthority));
-			}
-			vec.Add(professionItems);
-			if (professionOids != null)
-			{
-				vec.Add(professionOids);
-			}
-			if (registrationNumber != null)
-			{
-				vec.Add(new DerPrintableString(registrationNumber, true));
-			}
-			if (addProfessionInfo != null)
-			{
-				vec.Add(addProfessionInfo);
-			}
-			return new DerSequence(vec);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(true, 0, namingAuthority);
+            v.Add(professionItems);
+            v.AddOptional(professionOids);
+
+            if (registrationNumber != null)
+            {
+                v.Add(new DerPrintableString(registrationNumber, true));
+            }
+
+            v.AddOptional(addProfessionInfo);
+            return new DerSequence(v);
+        }
 
 		/**
 		* @return Returns the addProfessionInfo.
diff --git a/crypto/src/asn1/misc/IDEACBCPar.cs b/crypto/src/asn1/misc/IDEACBCPar.cs
index 72a60b9dc..9ae9f6faf 100644
--- a/crypto/src/asn1/misc/IDEACBCPar.cs
+++ b/crypto/src/asn1/misc/IDEACBCPar.cs
@@ -56,13 +56,8 @@ namespace Org.BouncyCastle.Asn1.Misc
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (iv != null)
-            {
-                v.Add(iv);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(iv);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/BasicOCSPResponse.cs b/crypto/src/asn1/ocsp/BasicOCSPResponse.cs
index e6aa1f86b..45dadba4f 100644
--- a/crypto/src/asn1/ocsp/BasicOCSPResponse.cs
+++ b/crypto/src/asn1/ocsp/BasicOCSPResponse.cs
@@ -123,15 +123,9 @@ namespace Org.BouncyCastle.Asn1.Ocsp
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				tbsResponseData, signatureAlgorithm, signature);
-
-			if (certs != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, certs));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(tbsResponseData, signatureAlgorithm, signature);
+            v.AddOptionalTagged(true, 0, certs);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/CrlID.cs b/crypto/src/asn1/ocsp/CrlID.cs
index cfb3d6fcb..3b3869a7a 100644
--- a/crypto/src/asn1/ocsp/CrlID.cs
+++ b/crypto/src/asn1/ocsp/CrlID.cs
@@ -60,23 +60,10 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (crlUrl != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, crlUrl));
-            }
-
-			if (crlNum != null)
-            {
-                v.Add(new DerTaggedObject(true, 1, crlNum));
-            }
-
-			if (crlTime != null)
-            {
-                v.Add(new DerTaggedObject(true, 2, crlTime));
-            }
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, crlUrl);
+            v.AddOptionalTagged(true, 1, crlNum);
+            v.AddOptionalTagged(true, 2, crlTime);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/OCSPRequest.cs b/crypto/src/asn1/ocsp/OCSPRequest.cs
index 2407678b4..6ecd29cae 100644
--- a/crypto/src/asn1/ocsp/OCSPRequest.cs
+++ b/crypto/src/asn1/ocsp/OCSPRequest.cs
@@ -77,13 +77,8 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(tbsRequest);
-
-			if (optionalSignature != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, optionalSignature));
-            }
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, optionalSignature);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/OCSPResponse.cs b/crypto/src/asn1/ocsp/OCSPResponse.cs
index 9477b61c0..649172947 100644
--- a/crypto/src/asn1/ocsp/OCSPResponse.cs
+++ b/crypto/src/asn1/ocsp/OCSPResponse.cs
@@ -78,13 +78,8 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(responseStatus);
-
-			if (responseBytes != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, responseBytes));
-            }
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, responseBytes);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/Request.cs b/crypto/src/asn1/ocsp/Request.cs
index 26e81ba70..21121cb28 100644
--- a/crypto/src/asn1/ocsp/Request.cs
+++ b/crypto/src/asn1/ocsp/Request.cs
@@ -79,13 +79,8 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(reqCert);
-
-			if (singleRequestExtensions != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, singleRequestExtensions));
-            }
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, singleRequestExtensions);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/ResponseData.cs b/crypto/src/asn1/ocsp/ResponseData.cs
index 70620cbc3..a5769c0fa 100644
--- a/crypto/src/asn1/ocsp/ResponseData.cs
+++ b/crypto/src/asn1/ocsp/ResponseData.cs
@@ -140,19 +140,14 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
 
-			if (versionPresent || !version.Equals(V1))
-			{
-				v.Add(new DerTaggedObject(true, 0, version));
-			}
-
-			v.Add(responderID, producedAt, responses);
-
-			if (responseExtensions != null)
+            if (versionPresent || !version.Equals(V1))
             {
-                v.Add(new DerTaggedObject(true, 1, responseExtensions));
+                v.Add(new DerTaggedObject(true, 0, version));
             }
 
-			return new DerSequence(v);
+            v.Add(responderID, producedAt, responses);
+            v.AddOptionalTagged(true, 1, responseExtensions);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/RevokedInfo.cs b/crypto/src/asn1/ocsp/RevokedInfo.cs
index ee9e55429..c67be0678 100644
--- a/crypto/src/asn1/ocsp/RevokedInfo.cs
+++ b/crypto/src/asn1/ocsp/RevokedInfo.cs
@@ -83,14 +83,9 @@ namespace Org.BouncyCastle.Asn1.Ocsp
          */
         public override Asn1Object ToAsn1Object()
         {
-			Asn1EncodableVector v = new Asn1EncodableVector(revocationTime);
-
-			if (revocationReason != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, revocationReason));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(revocationTime);
+            v.AddOptionalTagged(true, 0, revocationReason);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/ServiceLocator.cs b/crypto/src/asn1/ocsp/ServiceLocator.cs
index 4ba252be3..c6a9514ae 100644
--- a/crypto/src/asn1/ocsp/ServiceLocator.cs
+++ b/crypto/src/asn1/ocsp/ServiceLocator.cs
@@ -83,13 +83,8 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(issuer);
-
-			if (locator != null)
-            {
-                v.Add(locator);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(locator);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/Signature.cs b/crypto/src/asn1/ocsp/Signature.cs
index d6b4ccfbf..c6f149d62 100644
--- a/crypto/src/asn1/ocsp/Signature.cs
+++ b/crypto/src/asn1/ocsp/Signature.cs
@@ -101,15 +101,9 @@ namespace Org.BouncyCastle.Asn1.Ocsp
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				signatureAlgorithm, signatureValue);
-
-			if (certs != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, certs));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(signatureAlgorithm, signatureValue);
+            v.AddOptionalTagged(true, 0, certs);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/SingleResponse.cs b/crypto/src/asn1/ocsp/SingleResponse.cs
index 544232abe..ecdf3dab0 100644
--- a/crypto/src/asn1/ocsp/SingleResponse.cs
+++ b/crypto/src/asn1/ocsp/SingleResponse.cs
@@ -118,20 +118,10 @@ namespace Org.BouncyCastle.Asn1.Ocsp
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				certID, certStatus, thisUpdate);
-
-			if (nextUpdate != null)
-            {
-                v.Add(new DerTaggedObject(true, 0, nextUpdate));
-            }
-
-			if (singleExtensions != null)
-            {
-                v.Add(new DerTaggedObject(true, 1, singleExtensions));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(certID, certStatus, thisUpdate);
+            v.AddOptionalTagged(true, 0, nextUpdate);
+            v.AddOptionalTagged(true, 1, singleExtensions);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/ocsp/TBSRequest.cs b/crypto/src/asn1/ocsp/TBSRequest.cs
index 1ad8649f8..0166c5342 100644
--- a/crypto/src/asn1/ocsp/TBSRequest.cs
+++ b/crypto/src/asn1/ocsp/TBSRequest.cs
@@ -124,28 +124,19 @@ namespace Org.BouncyCastle.Asn1.Ocsp
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
 
-			//
-			// if default don't include - unless explicitly provided. Not strictly correct
-			// but required for some requests
-			//
-			if (!version.Equals(V1) || versionSet)
-			{
-                v.Add(new DerTaggedObject(true, 0, version));
-            }
-
-			if (requestorName != null)
+            //
+            // if default don't include - unless explicitly provided. Not strictly correct
+            // but required for some requests
+            //
+            if (!version.Equals(V1) || versionSet)
             {
-                v.Add(new DerTaggedObject(true, 1, requestorName));
-            }
-
-			v.Add(requestList);
-
-			if (requestExtensions != null)
-            {
-                v.Add(new DerTaggedObject(true, 2, requestExtensions));
+                v.Add(new DerTaggedObject(true, 0, version));
             }
 
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 1, requestorName);
+            v.Add(requestList);
+            v.AddOptionalTagged(true, 2, requestExtensions);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs
index 6d980131e..b775014b2 100644
--- a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs
+++ b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs
@@ -104,17 +104,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 			get { return attributes; }
 		}
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				version, subject, subjectPKInfo);
-
-			if (attributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, attributes));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(version, subject, subjectPKInfo);
+            v.AddOptionalTagged(false, 0, attributes);
+            return new DerSequence(v);
         }
 
         private static void ValidateAttributes(Asn1Set attributes)
diff --git a/crypto/src/asn1/pkcs/DHParameter.cs b/crypto/src/asn1/pkcs/DHParameter.cs
index 25a091a97..23be5d2ab 100644
--- a/crypto/src/asn1/pkcs/DHParameter.cs
+++ b/crypto/src/asn1/pkcs/DHParameter.cs
@@ -57,16 +57,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             get { return l == null ? null : l.PositiveValue; }
         }
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(p, g);
-
-			if (this.l != null)
-            {
-                v.Add(l);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(l);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs
index 279f30de8..13f469c6c 100644
--- a/crypto/src/asn1/pkcs/PBKDF2Params.cs
+++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs
@@ -126,13 +126,9 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-                octStr, iterationCount);
+            Asn1EncodableVector v = new Asn1EncodableVector(octStr, iterationCount);
+            v.AddOptional(keyLength);
 
-            if (keyLength != null)
-            {
-                v.Add(keyLength);
-            }
             if (!IsDefaultPrf)
             {
                 v.Add(prf);
diff --git a/crypto/src/asn1/pkcs/Pfx.cs b/crypto/src/asn1/pkcs/Pfx.cs
index 9676f64fc..4f958a070 100644
--- a/crypto/src/asn1/pkcs/Pfx.cs
+++ b/crypto/src/asn1/pkcs/Pfx.cs
@@ -49,17 +49,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 			get { return macData; }
 		}
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				new DerInteger(3), contentInfo);
-
-			if (macData != null)
-            {
-                v.Add(macData);
-            }
-
-			return new BerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(new DerInteger(3), contentInfo);
+            v.AddOptional(macData);
+            return new BerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
index dfb332fdd..ba9ef6a53 100644
--- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
+++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
@@ -187,17 +187,8 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(version, privateKeyAlgorithm, privateKey);
-
-            if (attributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, attributes));
-            }
-
-            if (publicKey != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, publicKey));
-            }
-
+            v.AddOptionalTagged(false, 0, attributes);
+            v.AddOptionalTagged(false, 1, publicKey);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/pkcs/RC2CBCParameter.cs b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
index 880ca7443..48591f2e9 100644
--- a/crypto/src/asn1/pkcs/RC2CBCParameter.cs
+++ b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
@@ -63,18 +63,12 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 			return Arrays.Clone(iv.GetOctets());
         }
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (version != null)
-            {
-                v.Add(version);
-            }
-
-			v.Add(iv);
-
-			return new DerSequence(v);
+            v.AddOptional(version);
+            v.Add(iv);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/SafeBag.cs b/crypto/src/asn1/pkcs/SafeBag.cs
index 4b9350bac..ea1ce951e 100644
--- a/crypto/src/asn1/pkcs/SafeBag.cs
+++ b/crypto/src/asn1/pkcs/SafeBag.cs
@@ -54,17 +54,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 			get { return bagAttributes; }
 		}
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				bagID, new DerTaggedObject(0, bagValue));
-
-			if (bagAttributes != null)
-            {
-                v.Add(bagAttributes);
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(bagID, new DerTaggedObject(0, bagValue));
+            v.AddOptional(bagAttributes);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/SignedData.cs b/crypto/src/asn1/pkcs/SignedData.cs
index 6e72bd0a9..3442e671c 100644
--- a/crypto/src/asn1/pkcs/SignedData.cs
+++ b/crypto/src/asn1/pkcs/SignedData.cs
@@ -136,21 +136,10 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-                version, digestAlgorithms, contentInfo);
-
-            if (certificates != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, certificates));
-            }
-
-            if (crls != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, crls));
-            }
-
+            Asn1EncodableVector v = new Asn1EncodableVector(version, digestAlgorithms, contentInfo);
+            v.AddOptionalTagged(false, 0, certificates);
+            v.AddOptionalTagged(false, 1, crls);
             v.Add(signerInfos);
-
             return new BerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/pkcs/SignerInfo.cs b/crypto/src/asn1/pkcs/SignerInfo.cs
index a3dc48b5b..c594b45e9 100644
--- a/crypto/src/asn1/pkcs/SignerInfo.cs
+++ b/crypto/src/asn1/pkcs/SignerInfo.cs
@@ -133,22 +133,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				version, issuerAndSerialNumber, digAlgorithm);
-
-			if (authenticatedAttributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, authenticatedAttributes));
-            }
-
-			v.Add(digEncryptionAlgorithm, encryptedDigest);
-
-			if (unauthenticatedAttributes != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes));
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(version, issuerAndSerialNumber, digAlgorithm);
+            v.AddOptionalTagged(false, 0, authenticatedAttributes);
+            v.Add(digEncryptionAlgorithm, encryptedDigest);
+            v.AddOptionalTagged(false, 1, unauthenticatedAttributes);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/smime/SMIMECapability.cs b/crypto/src/asn1/smime/SMIMECapability.cs
index 5709cb815..9b30c6dba 100644
--- a/crypto/src/asn1/smime/SMIMECapability.cs
+++ b/crypto/src/asn1/smime/SMIMECapability.cs
@@ -89,13 +89,8 @@ namespace Org.BouncyCastle.Asn1.Smime
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(capabilityID);
-
-			if (parameters != null)
-            {
-                v.Add(parameters);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(parameters);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/tsp/Accuracy.cs b/crypto/src/asn1/tsp/Accuracy.cs
index 9f2c7e8cc..c5a5ca119 100644
--- a/crypto/src/asn1/tsp/Accuracy.cs
+++ b/crypto/src/asn1/tsp/Accuracy.cs
@@ -126,26 +126,13 @@ namespace Org.BouncyCastle.Asn1.Tsp
 		 *             }
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (seconds != null)
-			{
-				v.Add(seconds);
-			}
-
-			if (millis != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, millis));
-			}
-
-			if (micros != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, micros));
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptional(seconds);
+            v.AddOptionalTagged(false, 0, millis);
+            v.AddOptionalTagged(false, 1, micros);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/tsp/TSTInfo.cs b/crypto/src/asn1/tsp/TSTInfo.cs
index 89f3e8b38..ee4dd67f1 100644
--- a/crypto/src/asn1/tsp/TSTInfo.cs
+++ b/crypto/src/asn1/tsp/TSTInfo.cs
@@ -214,37 +214,20 @@ namespace Org.BouncyCastle.Asn1.Tsp
 		 *
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				version, tsaPolicyId, messageImprint, serialNumber, genTime);
-
-			if (accuracy != null)
-			{
-				v.Add(accuracy);
-			}
-
-			if (ordering != null && ordering.IsTrue)
-			{
-				v.Add(ordering);
-			}
-
-			if (nonce != null)
-			{
-				v.Add(nonce);
-			}
-
-			if (tsa != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, tsa));
-			}
-
-			if (extensions != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, extensions));
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(version, tsaPolicyId, messageImprint, serialNumber, genTime);
+            v.AddOptional(accuracy);
+
+            if (ordering != null && ordering.IsTrue)
+            {
+                v.Add(ordering);
+            }
+
+            v.AddOptional(nonce);
+            v.AddOptionalTagged(true, 0, tsa);
+            v.AddOptionalTagged(false, 1, extensions);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/tsp/TimeStampReq.cs b/crypto/src/asn1/tsp/TimeStampReq.cs
index 5b05f3369..b71fe83ab 100644
--- a/crypto/src/asn1/tsp/TimeStampReq.cs
+++ b/crypto/src/asn1/tsp/TimeStampReq.cs
@@ -134,32 +134,18 @@ namespace Org.BouncyCastle.Asn1.Tsp
 		 * }
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				version, messageImprint);
-
-			if (tsaPolicy != null)
-			{
-				v.Add(tsaPolicy);
-			}
-
-			if (nonce != null)
-			{
-				v.Add(nonce);
-			}
-
-			if (certReq != null && certReq.IsTrue)
-			{
-				v.Add(certReq);
-			}
-
-			if (extensions != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, extensions));
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(version, messageImprint);
+            v.AddOptional(tsaPolicy, nonce);
+
+            if (certReq != null && certReq.IsTrue)
+            {
+                v.Add(certReq);
+            }
+
+            v.AddOptionalTagged(false, 0, extensions);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/tsp/TimeStampResp.cs b/crypto/src/asn1/tsp/TimeStampResp.cs
index b91026064..f5186ca4f 100644
--- a/crypto/src/asn1/tsp/TimeStampResp.cs
+++ b/crypto/src/asn1/tsp/TimeStampResp.cs
@@ -65,16 +65,11 @@ namespace Org.BouncyCastle.Asn1.Tsp
 		 *   timeStampToken          TimeStampToken     OPTIONAL  }
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo);
-
-			if (timeStampToken != null)
-			{
-				v.Add(timeStampToken);
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo);
+            v.AddOptional(timeStampToken);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x509/AttributeCertificateInfo.cs b/crypto/src/asn1/x509/AttributeCertificateInfo.cs
index 526f8e69b..a62b01981 100644
--- a/crypto/src/asn1/x509/AttributeCertificateInfo.cs
+++ b/crypto/src/asn1/x509/AttributeCertificateInfo.cs
@@ -136,21 +136,10 @@ namespace Org.BouncyCastle.Asn1.X509
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(
-				version, holder, issuer, signature, serialNumber,
-				attrCertValidityPeriod, attributes);
-
-			if (issuerUniqueID != null)
-            {
-                v.Add(issuerUniqueID);
-            }
-
-			if (extensions != null)
-            {
-                v.Add(extensions);
-            }
-
-			return new DerSequence(v);
+            Asn1EncodableVector v = new Asn1EncodableVector(version, holder, issuer, signature, serialNumber,
+                attrCertValidityPeriod, attributes);
+            v.AddOptional(issuerUniqueID, extensions);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/AuthorityKeyIdentifier.cs b/crypto/src/asn1/x509/AuthorityKeyIdentifier.cs
index d5a9048cc..aca1dc330 100644
--- a/crypto/src/asn1/x509/AuthorityKeyIdentifier.cs
+++ b/crypto/src/asn1/x509/AuthorityKeyIdentifier.cs
@@ -184,23 +184,10 @@ namespace Org.BouncyCastle.Asn1.X509
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (keyidentifier != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, keyidentifier));
-            }
-
-			if (certissuer != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, certissuer));
-            }
-
-			if (certserno != null)
-            {
-                v.Add(new DerTaggedObject(false, 2, certserno));
-            }
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(false, 0, keyidentifier);
+            v.AddOptionalTagged(false, 1, certissuer);
+            v.AddOptionalTagged(false, 2, certserno);
+            return new DerSequence(v);
         }
 
 		public override string ToString()
diff --git a/crypto/src/asn1/x509/BasicConstraints.cs b/crypto/src/asn1/x509/BasicConstraints.cs
index 098801f22..079294d1b 100644
--- a/crypto/src/asn1/x509/BasicConstraints.cs
+++ b/crypto/src/asn1/x509/BasicConstraints.cs
@@ -106,18 +106,9 @@ namespace Org.BouncyCastle.Asn1.X509
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (cA != null)
-			{
-				v.Add(cA);
-			}
-
-            if (pathLenConstraint != null)  // yes some people actually do this when cA is false...
-            {
-                v.Add(pathLenConstraint);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(cA,
+                pathLenConstraint); // yes some people actually do this when cA is false...
+            return new DerSequence(v);
         }
 
 		public override string ToString()
diff --git a/crypto/src/asn1/x509/CertificatePair.cs b/crypto/src/asn1/x509/CertificatePair.cs
index da9236010..69861e1dc 100644
--- a/crypto/src/asn1/x509/CertificatePair.cs
+++ b/crypto/src/asn1/x509/CertificatePair.cs
@@ -126,22 +126,13 @@ namespace Org.BouncyCastle.Asn1.X509
 		*
 		* @return a DERObject
 		*/
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-
-			if (forward != null)
-			{
-				vec.Add(new DerTaggedObject(0, forward));
-			}
-
-			if (reverse != null)
-			{
-				vec.Add(new DerTaggedObject(1, reverse));
-			}
-
-			return new DerSequence(vec);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(true, 0, forward);
+            v.AddOptionalTagged(true, 1, reverse);
+            return new DerSequence(v);
+        }
 
 		/**
 		* @return Returns the forward.
diff --git a/crypto/src/asn1/x509/DistributionPoint.cs b/crypto/src/asn1/x509/DistributionPoint.cs
index 40814c7a8..54ab930a5 100644
--- a/crypto/src/asn1/x509/DistributionPoint.cs
+++ b/crypto/src/asn1/x509/DistributionPoint.cs
@@ -92,29 +92,16 @@ namespace Org.BouncyCastle.Asn1.X509
 			get { return cRLIssuer; }
         }
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
 
-			if (distributionPoint != null)
-            {
-                //
-                // as this is a CHOICE it must be explicitly tagged
-                //
-                v.Add(new DerTaggedObject(0, distributionPoint));
-            }
-
-			if (reasons != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, reasons));
-            }
-
-			if (cRLIssuer != null)
-            {
-                v.Add(new DerTaggedObject(false, 2, cRLIssuer));
-            }
+            // As this is a CHOICE it must be explicitly tagged
+            v.AddOptionalTagged(true, 0, distributionPoint);
 
-			return new DerSequence(v);
+            v.AddOptionalTagged(false, 1, reasons);
+            v.AddOptionalTagged(false, 2, cRLIssuer);
+            return new DerSequence(v);
         }
 
 		public override string ToString()
diff --git a/crypto/src/asn1/x509/GeneralSubtree.cs b/crypto/src/asn1/x509/GeneralSubtree.cs
index e918a0277..a42ec4643 100644
--- a/crypto/src/asn1/x509/GeneralSubtree.cs
+++ b/crypto/src/asn1/x509/GeneralSubtree.cs
@@ -178,11 +178,7 @@ namespace Org.BouncyCastle.Asn1.X509
 				v.Add(new DerTaggedObject(false, 0, minimum));
 			}
 
-			if (maximum != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, maximum));
-			}
-
+            v.AddOptionalTagged(false, 1, maximum);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/x509/Holder.cs b/crypto/src/asn1/x509/Holder.cs
index 6e5315b80..b67c0b6c7 100644
--- a/crypto/src/asn1/x509/Holder.cs
+++ b/crypto/src/asn1/x509/Holder.cs
@@ -224,36 +224,23 @@ namespace Org.BouncyCastle.Asn1.X509
          *  }
          * </pre>
          */
-		public override Asn1Object ToAsn1Object()
-		{
-			if (version == 1)
-			{
-				Asn1EncodableVector v = new Asn1EncodableVector();
-
-				if (baseCertificateID != null)
-				{
-					v.Add(new DerTaggedObject(false, 0, baseCertificateID));
-				}
-
-				if (entityName != null)
-				{
-					v.Add(new DerTaggedObject(false, 1, entityName));
-				}
-
-				if (objectDigestInfo != null)
-				{
-					v.Add(new DerTaggedObject(false, 2, objectDigestInfo));
-				}
-
-				return new DerSequence(v);
-			}
+        public override Asn1Object ToAsn1Object()
+        {
+            if (version == 1)
+            {
+                Asn1EncodableVector v = new Asn1EncodableVector();
+                v.AddOptionalTagged(false, 0, baseCertificateID);
+                v.AddOptionalTagged(false, 1, entityName);
+                v.AddOptionalTagged(false, 2, objectDigestInfo);
+                return new DerSequence(v);
+            }
 
-			if (entityName != null)
-			{
-				return new DerTaggedObject(false, 1, entityName);
-			}
+            if (entityName != null)
+            {
+                return new DerTaggedObject(false, 1, entityName);
+            }
 
-			return new DerTaggedObject(false, 0, baseCertificateID);
-		}
+            return new DerTaggedObject(false, 0, baseCertificateID);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x509/IetfAttrSyntax.cs b/crypto/src/asn1/x509/IetfAttrSyntax.cs
index e719865b3..05313b1af 100644
--- a/crypto/src/asn1/x509/IetfAttrSyntax.cs
+++ b/crypto/src/asn1/x509/IetfAttrSyntax.cs
@@ -147,15 +147,9 @@ namespace Org.BouncyCastle.Asn1.X509
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (policyAuthority != null)
-            {
-                v.Add(new DerTaggedObject(0, policyAuthority));
-            }
-
-			v.Add(new DerSequence(values));
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, policyAuthority);
+            v.Add(new DerSequence(values));
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/IssuerSerial.cs b/crypto/src/asn1/x509/IssuerSerial.cs
index 1e47e022b..2c26339bd 100644
--- a/crypto/src/asn1/x509/IssuerSerial.cs
+++ b/crypto/src/asn1/x509/IssuerSerial.cs
@@ -84,17 +84,11 @@ namespace Org.BouncyCastle.Asn1.X509
          *  }
          * </pre>
          */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				issuer, serial);
-
-			if (issuerUid != null)
-			{
-				v.Add(issuerUid);
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(issuer, serial);
+            v.AddOptional(issuerUid);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x509/NameConstraints.cs b/crypto/src/asn1/x509/NameConstraints.cs
index 0c5fea8b3..b8cc7c0ab 100644
--- a/crypto/src/asn1/x509/NameConstraints.cs
+++ b/crypto/src/asn1/x509/NameConstraints.cs
@@ -100,21 +100,12 @@ namespace Org.BouncyCastle.Asn1.X509
 		 * NameConstraints ::= SEQUENCE { permittedSubtrees [0] GeneralSubtrees
 		 * OPTIONAL, excludedSubtrees [1] GeneralSubtrees OPTIONAL }
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (permitted != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, permitted));
-			}
-
-			if (excluded != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, excluded));
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(false, 0, permitted);
+            v.AddOptionalTagged(false, 1, excluded);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x509/ObjectDigestInfo.cs b/crypto/src/asn1/x509/ObjectDigestInfo.cs
index 9cd9a5f4c..190243cc6 100644
--- a/crypto/src/asn1/x509/ObjectDigestInfo.cs
+++ b/crypto/src/asn1/x509/ObjectDigestInfo.cs
@@ -162,18 +162,12 @@ namespace Org.BouncyCastle.Asn1.X509
 		 *   
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(digestedObjectType);
-
-			if (otherObjectTypeID != null)
-            {
-                v.Add(otherObjectTypeID);
-            }
-
-			v.Add(digestAlgorithm, objectDigest);
-
-			return new DerSequence(v);
+            v.AddOptional(otherObjectTypeID);
+            v.Add(digestAlgorithm, objectDigest);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/PolicyInformation.cs b/crypto/src/asn1/x509/PolicyInformation.cs
index 29d245084..90db29a36 100644
--- a/crypto/src/asn1/x509/PolicyInformation.cs
+++ b/crypto/src/asn1/x509/PolicyInformation.cs
@@ -68,13 +68,8 @@ namespace Org.BouncyCastle.Asn1.X509
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(policyIdentifier);
-
-			if (policyQualifiers != null)
-            {
-                v.Add(policyQualifiers);
-            }
-
-			return new DerSequence(v);
+            v.AddOptional(policyQualifiers);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs
index a3d7a3608..89e8de6cb 100644
--- a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs
+++ b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs
@@ -64,21 +64,12 @@ namespace Org.BouncyCastle.Asn1.X509
 			get { return _notAfter; }
 		}
 
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (_notBefore != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, _notBefore));
-			}
-
-			if (_notAfter != null)
-			{
-				v.Add(new DerTaggedObject(false, 1, _notAfter));
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(false, 0, _notBefore);
+            v.AddOptionalTagged(false, 1, _notAfter);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x509/RoleSyntax.cs b/crypto/src/asn1/x509/RoleSyntax.cs
index 48c3c6cae..b5b217b6b 100644
--- a/crypto/src/asn1/x509/RoleSyntax.cs
+++ b/crypto/src/asn1/x509/RoleSyntax.cs
@@ -190,19 +190,13 @@ namespace Org.BouncyCastle.Asn1.X509
 		*           }
 		* </pre>
 		*/
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector();
-
-			if (this.roleAuthority != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, roleAuthority));
-			}
-
-			v.Add(new DerTaggedObject(true, 1, roleName));
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptionalTagged(false, 0, roleAuthority);
+            v.Add(new DerTaggedObject(true, 1, roleName));
+            return new DerSequence(v);
+        }
 
 		public override string ToString()
 		{
diff --git a/crypto/src/asn1/x509/UserNotice.cs b/crypto/src/asn1/x509/UserNotice.cs
index f40916434..6311c7693 100644
--- a/crypto/src/asn1/x509/UserNotice.cs
+++ b/crypto/src/asn1/x509/UserNotice.cs
@@ -112,19 +112,9 @@ namespace Org.BouncyCastle.Asn1.X509
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector av = new Asn1EncodableVector();
-
-            if (noticeRef != null)
-            {
-                av.Add(noticeRef);
-            }
-
-            if (explicitText != null)
-            {
-                av.Add(explicitText);
-            }
-
-            return new DerSequence(av);
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptional(noticeRef, explicitText);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/V2Form.cs b/crypto/src/asn1/x509/V2Form.cs
index 2c6e54a77..53475ffbe 100644
--- a/crypto/src/asn1/x509/V2Form.cs
+++ b/crypto/src/asn1/x509/V2Form.cs
@@ -115,22 +115,9 @@ namespace Org.BouncyCastle.Asn1.X509
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector();
-
-            if (issuerName != null)
-            {
-                v.Add(issuerName);
-            }
-
-            if (baseCertificateID != null)
-            {
-                v.Add(new DerTaggedObject(false, 0, baseCertificateID));
-            }
-
-            if (objectDigestInfo != null)
-            {
-                v.Add(new DerTaggedObject(false, 1, objectDigestInfo));
-            }
-
+            v.AddOptional(issuerName);
+            v.AddOptionalTagged(false, 0, baseCertificateID);
+            v.AddOptionalTagged(false, 1, objectDigestInfo);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/x509/qualified/BiometricData.cs b/crypto/src/asn1/x509/qualified/BiometricData.cs
index bb70c342c..816ffd26d 100644
--- a/crypto/src/asn1/x509/qualified/BiometricData.cs
+++ b/crypto/src/asn1/x509/qualified/BiometricData.cs
@@ -94,17 +94,11 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified
 			get { return sourceDataUri; }
 		}
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector seq = new Asn1EncodableVector(
-				typeOfBiometricData, hashAlgorithm, biometricDataHash);
-
-			if (sourceDataUri != null)
-            {
-                seq.Add(sourceDataUri);
-            }
-
-			return new DerSequence(seq);
+            Asn1EncodableVector v = new Asn1EncodableVector(typeOfBiometricData, hashAlgorithm, biometricDataHash);
+            v.AddOptional(sourceDataUri);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/qualified/QCStatement.cs b/crypto/src/asn1/x509/qualified/QCStatement.cs
index a8e214cbf..bfa515392 100644
--- a/crypto/src/asn1/x509/qualified/QCStatement.cs
+++ b/crypto/src/asn1/x509/qualified/QCStatement.cs
@@ -69,16 +69,11 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified
 			get { return qcStatementInfo; }
 		}
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector seq = new Asn1EncodableVector(qcStatementId);
-
-			if (qcStatementInfo != null)
-            {
-                seq.Add(qcStatementInfo);
-            }
-
-			return new DerSequence(seq);
+            Asn1EncodableVector v = new Asn1EncodableVector(qcStatementId);
+            v.AddOptional(qcStatementInfo);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/qualified/SemanticsInformation.cs b/crypto/src/asn1/x509/qualified/SemanticsInformation.cs
index 5fe5f936c..379e6d1d1 100644
--- a/crypto/src/asn1/x509/qualified/SemanticsInformation.cs
+++ b/crypto/src/asn1/x509/qualified/SemanticsInformation.cs
@@ -104,21 +104,17 @@ namespace Org.BouncyCastle.Asn1.X509.Qualified
             return nameRegistrationAuthorities;
         }
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector seq = new Asn1EncodableVector();
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.AddOptional(semanticsIdentifier);
 
-            if (this.semanticsIdentifier != null)
+            if (null != nameRegistrationAuthorities)
             {
-                seq.Add(semanticsIdentifier);
+                v.Add(new DerSequence(nameRegistrationAuthorities));
             }
 
-			if (this.nameRegistrationAuthorities != null)
-            {
-                seq.Add(new DerSequence(nameRegistrationAuthorities));
-            }
-
-			return new DerSequence(seq);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/x509/sigi/PersonalData.cs b/crypto/src/asn1/x509/sigi/PersonalData.cs
index dba345c42..0e0bb5365 100644
--- a/crypto/src/asn1/x509/sigi/PersonalData.cs
+++ b/crypto/src/asn1/x509/sigi/PersonalData.cs
@@ -181,31 +181,25 @@ namespace Org.BouncyCastle.Asn1.X509.SigI
 		*
 		* @return an Asn1Object
 		*/
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector vec = new Asn1EncodableVector();
-			vec.Add(nameOrPseudonym);
-			if (nameDistinguisher != null)
-			{
-				vec.Add(new DerTaggedObject(false, 0, new DerInteger(nameDistinguisher)));
-			}
-			if (dateOfBirth != null)
-			{
-				vec.Add(new DerTaggedObject(false, 1, dateOfBirth));
-			}
-			if (placeOfBirth != null)
-			{
-				vec.Add(new DerTaggedObject(true, 2, placeOfBirth));
-			}
-			if (gender != null)
-			{
-				vec.Add(new DerTaggedObject(false, 3, new DerPrintableString(gender, true)));
-			}
-			if (postalAddress != null)
-			{
-				vec.Add(new DerTaggedObject(true, 4, postalAddress));
-			}
-			return new DerSequence(vec);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(nameOrPseudonym);
+
+            if (null != nameDistinguisher)
+            {
+                v.Add(new DerTaggedObject(false, 0, new DerInteger(nameDistinguisher)));
+            }
+
+            v.AddOptionalTagged(false, 1, dateOfBirth);
+            v.AddOptionalTagged(true, 2, placeOfBirth);
+
+            if (null != gender)
+            {
+                v.Add(new DerTaggedObject(false, 3, new DerPrintableString(gender, true)));
+            }
+
+            v.AddOptionalTagged(true, 4, postalAddress);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x9/DHDomainParameters.cs b/crypto/src/asn1/x9/DHDomainParameters.cs
index b8c1ac030..a92322717 100644
--- a/crypto/src/asn1/x9/DHDomainParameters.cs
+++ b/crypto/src/asn1/x9/DHDomainParameters.cs
@@ -98,21 +98,11 @@ namespace Org.BouncyCastle.Asn1.X9
 			get { return this.validationParms; }
 		}
 
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(p, g, q);
-
-			if (this.j != null)
-			{
-				v.Add(this.j);
-			}
-
-			if (this.validationParms != null)
-			{
-				v.Add(this.validationParms);
-			}
-
-			return new DerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(p, g, q);
+            v.AddOptional(j, validationParms);
+            return new DerSequence(v);
+        }
 	}
 }
diff --git a/crypto/src/asn1/x9/OtherInfo.cs b/crypto/src/asn1/x9/OtherInfo.cs
index 21863bd17..4a52b7206 100644
--- a/crypto/src/asn1/x9/OtherInfo.cs
+++ b/crypto/src/asn1/x9/OtherInfo.cs
@@ -74,15 +74,9 @@ namespace Org.BouncyCastle.Asn1.X9
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(keyInfo);
-
-			if (partyAInfo != null)
-            {
-                v.Add(new DerTaggedObject(0, partyAInfo));
-            }
-
-			v.Add(new DerTaggedObject(2, suppPubInfo));
-
-			return new DerSequence(v);
+            v.AddOptionalTagged(true, 0, partyAInfo);
+            v.Add(new DerTaggedObject(2, suppPubInfo));
+            return new DerSequence(v);
         }
     }
 }