//   NOTE: this is a machine generated file--editing not recommended
//
// sm_x509af.cpp - class member functions for ASN.1 module AuthenticationFramework
//
//   This file was generated by snacc on Mon Apr 22 22:34:19 2002
//   UBC snacc written by Mike Sample
//   A couple of enhancements made by IBM European Networking Center


#include "asn-incl.h"
#include "sm_vdatypes.h"
#include "sm_x501ud.h"
#include "sm_x411ub.h"
#include "sm_x411mtsas.h"
#include "sm_x501if.h"
#include "sm_x520sa.h"
#include "sm_x509cmn.h"
#include "sm_x509af.h"
#include "sm_x509ce.h"
#include "pkcs1oids.h"
#include "pkcs9oids.h"
#include "sm_cms.h"
#include "sm_ess.h"
#include "pkcs7.h"
#include "pkcs8.h"
#include "appleoids.h"
#include "pkcs10.h"

//------------------------------------------------------------------------------
// value defs


//------------------------------------------------------------------------------
// class member definitions:

AsnType *AttributeCertificateAssertionSetOf::Clone() const
{
  return new AttributeCertificateAssertionSetOf;
}

AsnType *AttributeCertificateAssertionSetOf::Copy() const
{
  return new AttributeCertificateAssertionSetOf (*this);
}

AsnLen AttributeCertificateAssertionSetOf::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void AttributeCertificateAssertionSetOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "AttributeCertificateAssertionSetOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-100);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

AttributeCertificateAssertionSetOf::AttributeCertificateAssertionSetOf (const AttributeCertificateAssertionSetOf &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateAssertionSetOf::AttributeCertificateAssertionSetOf (const AttributeCertificateAssertionSetOf &)" << endl;
  abort();
}

AttributeCertificateAssertionSetOf::~AttributeCertificateAssertionSetOf()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &that)
#else // SNACC_DEEP_COPY
AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::operator = (const AttributeCertificateAssertionSetOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeCertificateAssertionSetOf::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  AttributeCertificateAssertionSetOf::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // AttributeCertificateAssertionSetOf::SetCurrElmt


unsigned long int  AttributeCertificateAssertionSetOf::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // AttributeCertificateAssertionSetOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
AttributeType *AttributeCertificateAssertionSetOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new AttributeType;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateAssertionSetOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
AttributeType  *AttributeCertificateAssertionSetOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateAssertionSetOf::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
AttributeType  *AttributeCertificateAssertionSetOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateAssertionSetOf::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
AttributeType *AttributeCertificateAssertionSetOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateAssertionSetOf::InsertAfter


AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::AppendCopy (AttributeType &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::PrependCopy (AttributeType &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateAssertionSetOf::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
AttributeCertificateAssertionSetOf &AttributeCertificateAssertionSetOf::InsertBeforeAndCopy (AttributeType &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateAssertionSetOf::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
AttributeCertificateAssertionSetOf  &AttributeCertificateAssertionSetOf::InsertAfterAndCopy (AttributeType &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeType;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateAssertionSetOf::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void AttributeCertificateAssertionSetOf::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen AttributeCertificateAssertionSetOf::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncDefLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, PRIM, OID_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // AttributeCertificateAssertionSetOf::BEncContent


void  AttributeCertificateAssertionSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    AttributeType *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-101);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // AttributeCertificateAssertionSetOf::BDecContent


AsnType *AttributeCertificateInfoSeqOf::Clone() const
{
  return new AttributeCertificateInfoSeqOf;
}

AsnType *AttributeCertificateInfoSeqOf::Copy() const
{
  return new AttributeCertificateInfoSeqOf (*this);
}

AsnLen AttributeCertificateInfoSeqOf::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificateInfoSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificateInfoSeqOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-102);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

AttributeCertificateInfoSeqOf::AttributeCertificateInfoSeqOf (const AttributeCertificateInfoSeqOf &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateInfoSeqOf::AttributeCertificateInfoSeqOf (const AttributeCertificateInfoSeqOf &)" << endl;
  abort();
}

AttributeCertificateInfoSeqOf::~AttributeCertificateInfoSeqOf()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &that)
#else // SNACC_DEEP_COPY
AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::operator = (const AttributeCertificateInfoSeqOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeCertificateInfoSeqOf::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  AttributeCertificateInfoSeqOf::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // AttributeCertificateInfoSeqOf::SetCurrElmt


unsigned long int  AttributeCertificateInfoSeqOf::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // AttributeCertificateInfoSeqOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
Attribute *AttributeCertificateInfoSeqOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new Attribute;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateInfoSeqOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
Attribute  *AttributeCertificateInfoSeqOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateInfoSeqOf::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
Attribute  *AttributeCertificateInfoSeqOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateInfoSeqOf::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
Attribute *AttributeCertificateInfoSeqOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificateInfoSeqOf::InsertAfter


AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::AppendCopy (Attribute &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::PrependCopy (Attribute &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateInfoSeqOf::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
AttributeCertificateInfoSeqOf &AttributeCertificateInfoSeqOf::InsertBeforeAndCopy (Attribute &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateInfoSeqOf::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
AttributeCertificateInfoSeqOf  &AttributeCertificateInfoSeqOf::InsertAfterAndCopy (Attribute &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Attribute;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificateInfoSeqOf::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void AttributeCertificateInfoSeqOf::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen AttributeCertificateInfoSeqOf::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // AttributeCertificateInfoSeqOf::BEncContent


void  AttributeCertificateInfoSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    Attribute *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-103);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // AttributeCertificateInfoSeqOf::BDecContent


AlgorithmIdentifier::AlgorithmIdentifier()
{
  parameters = NULL;
}

AlgorithmIdentifier::AlgorithmIdentifier (const AlgorithmIdentifier &)
{
  Asn1Error << "use of incompletely defined AlgorithmIdentifier::AlgorithmIdentifier (const AlgorithmIdentifier &)" << endl;
  abort();
}

AlgorithmIdentifier::~AlgorithmIdentifier()
{
  delete parameters;
}

AsnType *AlgorithmIdentifier::Clone() const
{
  return new AlgorithmIdentifier;
}

AsnType *AlgorithmIdentifier::Copy() const
{
  return new AlgorithmIdentifier (*this);
}

#if SNACC_DEEP_COPY
AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &that)
#else // SNACC_DEEP_COPY
AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    algorithm = that.algorithm;
    if (that.parameters)
    {
      if (!parameters)
        parameters = new AsnAny;
      *parameters = *that.parameters;
    }
    else
    {
      delete parameters;
      parameters = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AlgorithmIdentifier &AlgorithmIdentifier::operator = (const AlgorithmIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AlgorithmIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (parameters))
  {
        ENC_LOAD_ANYBUF(parameters, b, l);
    totalLen += l;
  }

    l = algorithm.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // AlgorithmIdentifier::BEncContent


void AlgorithmIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithm.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = b.PeekByte();

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDecEoc (b, seqBytesDecoded, env);

        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-104);
  }

  // ANY type
    parameters = new AsnAny;
        DEC_LOAD_ANYBUF(parameters, b, seqBytesDecoded, env);


  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-105);
  }
  else
    return;
} // AlgorithmIdentifier::BDecContent

AsnLen AlgorithmIdentifier::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AlgorithmIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AlgorithmIdentifier::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-106);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AlgorithmIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "algorithm ";
    os << algorithm;
    os << "," << endl;
  }

  if (NOT_NULL (parameters))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "parameters ";
    os << *parameters;
  }
  else
  {
    Indent (os, indentG);
    os << "parameters ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AlgorithmIdentifier::Print


Time::Time()
{
  choiceId = utcTimeCid;
#if TCL
  utcTime = new UTCTime;
#else
  utcTime = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

Time::Time (const Time &)
{
  Asn1Error << "use of incompletely defined Time::Time (const Time &)" << endl;
  abort();
}

Time::~Time()
{
  switch (choiceId)
  {
    case utcTimeCid:
      delete utcTime;
      break;
    case generalizedTimeCid:
      delete generalizedTime;
      break;
  } // end of switch
} // end of destructor

AsnType *Time::Clone() const
{
  return new Time;
}

AsnType *Time::Copy() const
{
  return new Time (*this);
}

#if SNACC_DEEP_COPY
Time &Time::operator = (const Time &that)
#else // SNACC_DEEP_COPY
Time &Time::operator = (const Time &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case utcTimeCid:
        delete utcTime;
        break;
      case generalizedTimeCid:
        delete generalizedTime;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case utcTimeCid:
        utcTime = new UTCTime;
        *utcTime = *that.utcTime;
        break;
      case generalizedTimeCid:
        generalizedTime = new GeneralizedTime;
        *generalizedTime = *that.generalizedTime;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Time &Time::operator = (const Time &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
Time::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case utcTimeCid:
      l = utcTime->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, UTCTIME_TAG_CODE);
      break;

    case generalizedTimeCid:
      l = generalizedTime->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
      break;

  } // end switch
  return l;
} // Time::BEncContent


void Time::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE):
    case MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE):
      choiceId = utcTimeCid;
      utcTime = new UTCTime;
        utcTime->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE):
    case MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE):
      choiceId = generalizedTimeCid;
      generalizedTime = new GeneralizedTime;
        generalizedTime->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-107);
      break;
  } // end switch
} // Time::BDecContent


AsnLen Time::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void Time::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void Time::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case utcTimeCid:
      os << "utcTime ";
      if (utcTime)
        os << *utcTime;
      else
        os << "-- void3 --\n";
      break;

    case generalizedTimeCid:
      os << "generalizedTime ";
      if (generalizedTime)
        os << *generalizedTime;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // Time::Print

Extension::Extension()
{
  critical = NULL;
}

Extension::Extension (const Extension &)
{
  Asn1Error << "use of incompletely defined Extension::Extension (const Extension &)" << endl;
  abort();
}

Extension::~Extension()
{
  delete critical;
}

AsnType *Extension::Clone() const
{
  return new Extension;
}

AsnType *Extension::Copy() const
{
  return new Extension (*this);
}

#if SNACC_DEEP_COPY
Extension &Extension::operator = (const Extension &that)
#else // SNACC_DEEP_COPY
Extension &Extension::operator = (const Extension &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    extnId = that.extnId;
    if (that.critical)
    {
      if (!critical)
        critical = new AsnBool;
      *critical = *that.critical;
    }
    else
    {
      delete critical;
      critical = NULL;
    }
    extnValue = that.extnValue;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Extension &Extension::operator = (const Extension &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
Extension::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = extnValue.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (critical))
  {
    l = critical->BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, BOOLEAN_TAG_CODE);
    totalLen += l;
  }

    l = extnId.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // Extension::BEncContent


void Extension::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    extnId.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-108);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BOOLEAN_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    critical = new AsnBool;
    critical->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    extnValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-109);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-110);
  }
  else
    return;
} // Extension::BDecContent

AsnLen Extension::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void Extension::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "Extension::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-111);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void Extension::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "extnId ";
    os << extnId;
    os << "," << endl;
  }

  if (NOT_NULL (critical))
  {
    Indent (os, indentG);
    os << "critical ";
    os << *critical;
  }
  else
  {
    Indent (os, indentG);
    os << "critical ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "extnValue ";
    os << extnValue;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // Extension::Print


AttCertValidityPeriod::AttCertValidityPeriod()
{
}

AttCertValidityPeriod::AttCertValidityPeriod (const AttCertValidityPeriod &)
{
  Asn1Error << "use of incompletely defined AttCertValidityPeriod::AttCertValidityPeriod (const AttCertValidityPeriod &)" << endl;
  abort();
}

AttCertValidityPeriod::~AttCertValidityPeriod()
{
}

AsnType *AttCertValidityPeriod::Clone() const
{
  return new AttCertValidityPeriod;
}

AsnType *AttCertValidityPeriod::Copy() const
{
  return new AttCertValidityPeriod (*this);
}

#if SNACC_DEEP_COPY
AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &that)
#else // SNACC_DEEP_COPY
AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    notBeforeTime = that.notBeforeTime;
    notAfterTime = that.notAfterTime;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttCertValidityPeriod &AttCertValidityPeriod::operator = (const AttCertValidityPeriod &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttCertValidityPeriod::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = notAfterTime.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
    totalLen += l;

    l = notBeforeTime.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
    totalLen += l;

  return totalLen;
} // AttCertValidityPeriod::BEncContent


void AttCertValidityPeriod::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    notBeforeTime.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-112);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    notAfterTime.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-113);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-114);
  }
  else
    return;
} // AttCertValidityPeriod::BDecContent

AsnLen AttCertValidityPeriod::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttCertValidityPeriod::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttCertValidityPeriod::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-115);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AttCertValidityPeriod::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "notBeforeTime ";
    os << notBeforeTime;
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "notAfterTime ";
    os << notAfterTime;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AttCertValidityPeriod::Print


Validity::Validity()
{
#if TCL
  notBefore = new Time;
#else
  notBefore = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  notAfter = new Time;
#else
  notAfter = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

Validity::Validity (const Validity &)
{
  Asn1Error << "use of incompletely defined Validity::Validity (const Validity &)" << endl;
  abort();
}

Validity::~Validity()
{
  delete notBefore;
  delete notAfter;
}

AsnType *Validity::Clone() const
{
  return new Validity;
}

AsnType *Validity::Copy() const
{
  return new Validity (*this);
}

#if SNACC_DEEP_COPY
Validity &Validity::operator = (const Validity &that)
#else // SNACC_DEEP_COPY
Validity &Validity::operator = (const Validity &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.notBefore)
    {
      if (!notBefore)
        notBefore = new Time;
      *notBefore = *that.notBefore;
    }
    else
    {
      delete notBefore;
      notBefore = NULL;
    }
    if (that.notAfter)
    {
      if (!notAfter)
        notAfter = new Time;
      *notAfter = *that.notAfter;
    }
    else
    {
      delete notAfter;
      notAfter = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Validity &Validity::operator = (const Validity &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
Validity::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = notAfter->BEncContent (b);
    totalLen += l;

    l = notBefore->BEncContent (b);
    totalLen += l;

  return totalLen;
} // Validity::BEncContent


void Validity::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    notBefore = new Time;
    notBefore->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-116);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    notAfter = new Time;
    notAfter->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-117);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-118);
  }
  else
    return;
} // Validity::BDecContent

AsnLen Validity::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void Validity::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "Validity::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-119);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void Validity::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (notBefore))
  {
    Indent (os, indentG);
    os << "notBefore ";
    os << *notBefore;
  }
  else
  {
    Indent (os, indentG);
    os << "notBefore ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (notAfter))
  {
    Indent (os, indentG);
    os << "notAfter ";
    os << *notAfter;
  }
  else
  {
    Indent (os, indentG);
    os << "notAfter ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // Validity::Print


SubjectPublicKeyInfo::SubjectPublicKeyInfo()
{
#if TCL
  algorithm = new AlgorithmIdentifier;
#else
  algorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

SubjectPublicKeyInfo::SubjectPublicKeyInfo (const SubjectPublicKeyInfo &)
{
  Asn1Error << "use of incompletely defined SubjectPublicKeyInfo::SubjectPublicKeyInfo (const SubjectPublicKeyInfo &)" << endl;
  abort();
}

SubjectPublicKeyInfo::~SubjectPublicKeyInfo()
{
  delete algorithm;
}

AsnType *SubjectPublicKeyInfo::Clone() const
{
  return new SubjectPublicKeyInfo;
}

AsnType *SubjectPublicKeyInfo::Copy() const
{
  return new SubjectPublicKeyInfo (*this);
}

#if SNACC_DEEP_COPY
SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &that)
#else // SNACC_DEEP_COPY
SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.algorithm)
    {
      if (!algorithm)
        algorithm = new AlgorithmIdentifier;
      *algorithm = *that.algorithm;
    }
    else
    {
      delete algorithm;
      algorithm = NULL;
    }
    subjectPublicKey = that.subjectPublicKey;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined SubjectPublicKeyInfo &SubjectPublicKeyInfo::operator = (const SubjectPublicKeyInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
SubjectPublicKeyInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = subjectPublicKey.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = algorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // SubjectPublicKeyInfo::BEncContent


void SubjectPublicKeyInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithm = new AlgorithmIdentifier;
    algorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-120);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subjectPublicKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-121);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-122);
  }
  else
    return;
} // SubjectPublicKeyInfo::BDecContent

AsnLen SubjectPublicKeyInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void SubjectPublicKeyInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "SubjectPublicKeyInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-123);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void SubjectPublicKeyInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (algorithm))
  {
    Indent (os, indentG);
    os << "algorithm ";
    os << *algorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "algorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "subjectPublicKey ";
    os << subjectPublicKey;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // SubjectPublicKeyInfo::Print


AsnType *Extensions::Clone() const
{
  return new Extensions;
}

AsnType *Extensions::Copy() const
{
  return new Extensions (*this);
}

AsnLen Extensions::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void Extensions::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "Extensions::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-124);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

Extensions::Extensions (const Extensions &)
{
  Asn1Error << "use of incompletely defined Extensions::Extensions (const Extensions &)" << endl;
  abort();
}

Extensions::~Extensions()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
Extensions &Extensions::operator = (const Extensions &that)
#else // SNACC_DEEP_COPY
Extensions &Extensions::operator = (const Extensions &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Extensions &Extensions::operator = (const Extensions &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void Extensions::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  Extensions::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // Extensions::SetCurrElmt


unsigned long int  Extensions::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // Extensions::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
Extension *Extensions::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new Extension;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // Extensions::Append


// alloc new list elmt, put at begining of list
//  and return the component type
Extension  *Extensions::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // Extensions::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
Extension  *Extensions::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // Extensions::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
Extension *Extensions::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // Extensions::InsertAfter


Extensions  &Extensions::AppendCopy (Extension &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


Extensions  &Extensions::PrependCopy (Extension &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // Extensions::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
Extensions &Extensions::InsertBeforeAndCopy (Extension &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // Extensions::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
Extensions  &Extensions::InsertAfterAndCopy (Extension &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Extension;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // Extensions::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void Extensions::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen Extensions::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // Extensions::BEncContent


void  Extensions::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    Extension *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-125);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // Extensions::BDecContent


IssuerSerial::IssuerSerial()
{
  issuerUID = NULL;
}

IssuerSerial::IssuerSerial (const IssuerSerial &)
{
  Asn1Error << "use of incompletely defined IssuerSerial::IssuerSerial (const IssuerSerial &)" << endl;
  abort();
}

IssuerSerial::~IssuerSerial()
{
  delete issuerUID;
}

AsnType *IssuerSerial::Clone() const
{
  return new IssuerSerial;
}

AsnType *IssuerSerial::Copy() const
{
  return new IssuerSerial (*this);
}

#if SNACC_DEEP_COPY
IssuerSerial &IssuerSerial::operator = (const IssuerSerial &that)
#else // SNACC_DEEP_COPY
IssuerSerial &IssuerSerial::operator = (const IssuerSerial &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    issuer = that.issuer;
    serial = that.serial;
    if (that.issuerUID)
    {
      if (!issuerUID)
        issuerUID = new UniqueIdentifier;
      *issuerUID = *that.issuerUID;
    }
    else
    {
      delete issuerUID;
      issuerUID = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined IssuerSerial &IssuerSerial::operator = (const IssuerSerial &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
IssuerSerial::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (issuerUID))
  {
    l = issuerUID->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;
  }

    l = serial.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = issuer.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // IssuerSerial::BEncContent


void IssuerSerial::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuer.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-126);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    serial.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-127);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuerUID = new UniqueIdentifier;
    issuerUID->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-128);
  }
  else
    return;
} // IssuerSerial::BDecContent

AsnLen IssuerSerial::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void IssuerSerial::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "IssuerSerial::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-129);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void IssuerSerial::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "issuer ";
    os << issuer;
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "serial ";
    os << serial;
    os << "," << endl;
  }

  if (NOT_NULL (issuerUID))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "issuerUID ";
    os << *issuerUID;
  }
  else
  {
    Indent (os, indentG);
    os << "issuerUID ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // IssuerSerial::Print


AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice()
{
  choiceId = baseCertificateIDCid;
#if TCL
  baseCertificateID = new IssuerSerial;
#else
  baseCertificateID = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice (const AttributeCertificateAssertionChoice &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateAssertionChoice::AttributeCertificateAssertionChoice (const AttributeCertificateAssertionChoice &)" << endl;
  abort();
}

AttributeCertificateAssertionChoice::~AttributeCertificateAssertionChoice()
{
  switch (choiceId)
  {
    case baseCertificateIDCid:
      delete baseCertificateID;
      break;
    case subjectNameCid:
      delete subjectName;
      break;
  } // end of switch
} // end of destructor

AsnType *AttributeCertificateAssertionChoice::Clone() const
{
  return new AttributeCertificateAssertionChoice;
}

AsnType *AttributeCertificateAssertionChoice::Copy() const
{
  return new AttributeCertificateAssertionChoice (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &that)
#else // SNACC_DEEP_COPY
AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case baseCertificateIDCid:
        delete baseCertificateID;
        break;
      case subjectNameCid:
        delete subjectName;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case baseCertificateIDCid:
        baseCertificateID = new IssuerSerial;
        *baseCertificateID = *that.baseCertificateID;
        break;
      case subjectNameCid:
        subjectName = new Name;
        *subjectName = *that.subjectName;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateAssertionChoice &AttributeCertificateAssertionChoice::operator = (const AttributeCertificateAssertionChoice &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificateAssertionChoice::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case baseCertificateIDCid:
      BEncEocIfNec (b);
      BEncEocIfNec (b);
      l = baseCertificateID->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
      break;

    case subjectNameCid:
      BEncEocIfNec (b);
      l = subjectName->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
      break;

  } // end switch
  return l;
} // AttributeCertificateAssertionChoice::BEncContent


void AttributeCertificateAssertionChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnLen elmtLen1;
  switch (tag)
  {
    case MAKE_TAG_ID (CNTX, CONS, 0):
      tag = BDecTag (b, bytesDecoded, env);
      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
      {
         Asn1Error << "Unexpected Tag" << endl;
        SnaccExcep::throwMe(-130);
      }

      elmtLen1 = BDecLen (b, bytesDecoded, env);
      choiceId = baseCertificateIDCid;
      baseCertificateID = new IssuerSerial;
        baseCertificateID->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
      if (elmtLen0 == INDEFINITE_LEN)
        BDecEoc (b, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 1):
      tag = BDecTag (b, bytesDecoded, env);
      elmtLen1 = BDecLen (b, bytesDecoded, env);
      choiceId = subjectNameCid;
      subjectName = new Name;
        subjectName->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
      if (elmtLen0 == INDEFINITE_LEN)
        BDecEoc (b, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-131);
      break;
  } // end switch
} // AttributeCertificateAssertionChoice::BDecContent


AsnLen AttributeCertificateAssertionChoice::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void AttributeCertificateAssertionChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void AttributeCertificateAssertionChoice::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case baseCertificateIDCid:
      os << "baseCertificateID ";
      if (baseCertificateID)
        os << *baseCertificateID;
      else
        os << "-- void3 --\n";
      break;

    case subjectNameCid:
      os << "subjectName ";
      if (subjectName)
        os << *subjectName;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // AttributeCertificateAssertionChoice::Print

AttributeCertificateInfoChoice::AttributeCertificateInfoChoice()
{
  choiceId = baseCertificateIDCid;
#if TCL
  baseCertificateID = new IssuerSerial;
#else
  baseCertificateID = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

AttributeCertificateInfoChoice::AttributeCertificateInfoChoice (const AttributeCertificateInfoChoice &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateInfoChoice::AttributeCertificateInfoChoice (const AttributeCertificateInfoChoice &)" << endl;
  abort();
}

AttributeCertificateInfoChoice::~AttributeCertificateInfoChoice()
{
  switch (choiceId)
  {
    case baseCertificateIDCid:
      delete baseCertificateID;
      break;
    case subjectNameCid:
      delete subjectName;
      break;
  } // end of switch
} // end of destructor

AsnType *AttributeCertificateInfoChoice::Clone() const
{
  return new AttributeCertificateInfoChoice;
}

AsnType *AttributeCertificateInfoChoice::Copy() const
{
  return new AttributeCertificateInfoChoice (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &that)
#else // SNACC_DEEP_COPY
AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case baseCertificateIDCid:
        delete baseCertificateID;
        break;
      case subjectNameCid:
        delete subjectName;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case baseCertificateIDCid:
        baseCertificateID = new IssuerSerial;
        *baseCertificateID = *that.baseCertificateID;
        break;
      case subjectNameCid:
        subjectName = new GeneralNames;
        *subjectName = *that.subjectName;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateInfoChoice &AttributeCertificateInfoChoice::operator = (const AttributeCertificateInfoChoice &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificateInfoChoice::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case baseCertificateIDCid:
      BEncEocIfNec (b);
      BEncEocIfNec (b);
      l = baseCertificateID->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
      break;

    case subjectNameCid:
      BEncEocIfNec (b);
      BEncEocIfNec (b);
      l = subjectName->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
      break;

  } // end switch
  return l;
} // AttributeCertificateInfoChoice::BEncContent


void AttributeCertificateInfoChoice::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnLen elmtLen1;
  switch (tag)
  {
    case MAKE_TAG_ID (CNTX, CONS, 0):
      tag = BDecTag (b, bytesDecoded, env);
      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
      {
         Asn1Error << "Unexpected Tag" << endl;
        SnaccExcep::throwMe(-132);
      }

      elmtLen1 = BDecLen (b, bytesDecoded, env);
      choiceId = baseCertificateIDCid;
      baseCertificateID = new IssuerSerial;
        baseCertificateID->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
      if (elmtLen0 == INDEFINITE_LEN)
        BDecEoc (b, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 1):
      tag = BDecTag (b, bytesDecoded, env);
      if (tag != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
      {
         Asn1Error << "Unexpected Tag" << endl;
        SnaccExcep::throwMe(-133);
      }

      elmtLen1 = BDecLen (b, bytesDecoded, env);
      choiceId = subjectNameCid;
      subjectName = new GeneralNames;
        subjectName->BDecContent (b, tag, elmtLen1, bytesDecoded, env);
      if (elmtLen0 == INDEFINITE_LEN)
        BDecEoc (b, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-134);
      break;
  } // end switch
} // AttributeCertificateInfoChoice::BDecContent


AsnLen AttributeCertificateInfoChoice::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void AttributeCertificateInfoChoice::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void AttributeCertificateInfoChoice::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case baseCertificateIDCid:
      os << "baseCertificateID ";
      if (baseCertificateID)
        os << *baseCertificateID;
      else
        os << "-- void3 --\n";
      break;

    case subjectNameCid:
      os << "subjectName ";
      if (subjectName)
        os << *subjectName;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // AttributeCertificateInfoChoice::Print

CRLToSignSeqOfSeq::CRLToSignSeqOfSeq()
{
#if TCL
  revocationDate = new Time;
#else
  revocationDate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  crlEntryExtensions = NULL;
}

CRLToSignSeqOfSeq::CRLToSignSeqOfSeq (const CRLToSignSeqOfSeq &)
{
  Asn1Error << "use of incompletely defined CRLToSignSeqOfSeq::CRLToSignSeqOfSeq (const CRLToSignSeqOfSeq &)" << endl;
  abort();
}

CRLToSignSeqOfSeq::~CRLToSignSeqOfSeq()
{
  delete revocationDate;
  delete crlEntryExtensions;
}

AsnType *CRLToSignSeqOfSeq::Clone() const
{
  return new CRLToSignSeqOfSeq;
}

AsnType *CRLToSignSeqOfSeq::Copy() const
{
  return new CRLToSignSeqOfSeq (*this);
}

#if SNACC_DEEP_COPY
CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &that)
#else // SNACC_DEEP_COPY
CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    userCertificate = that.userCertificate;
    if (that.revocationDate)
    {
      if (!revocationDate)
        revocationDate = new Time;
      *revocationDate = *that.revocationDate;
    }
    else
    {
      delete revocationDate;
      revocationDate = NULL;
    }
    if (that.crlEntryExtensions)
    {
      if (!crlEntryExtensions)
        crlEntryExtensions = new Extensions;
      *crlEntryExtensions = *that.crlEntryExtensions;
    }
    else
    {
      delete crlEntryExtensions;
      crlEntryExtensions = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CRLToSignSeqOfSeq &CRLToSignSeqOfSeq::operator = (const CRLToSignSeqOfSeq &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CRLToSignSeqOfSeq::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (crlEntryExtensions))
  {
      BEncEocIfNec (b);
    l = crlEntryExtensions->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

    l = revocationDate->BEncContent (b);
    totalLen += l;

    l = userCertificate.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // CRLToSignSeqOfSeq::BEncContent


void CRLToSignSeqOfSeq::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    userCertificate.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-135);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    revocationDate = new Time;
    revocationDate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-136);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    crlEntryExtensions = new Extensions;
    crlEntryExtensions->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-137);
  }
  else
    return;
} // CRLToSignSeqOfSeq::BDecContent

AsnLen CRLToSignSeqOfSeq::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CRLToSignSeqOfSeq::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CRLToSignSeqOfSeq::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-138);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CRLToSignSeqOfSeq::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "userCertificate ";
    os << userCertificate;
    os << "," << endl;
  }

  if (NOT_NULL (revocationDate))
  {
    Indent (os, indentG);
    os << "revocationDate ";
    os << *revocationDate;
  }
  else
  {
    Indent (os, indentG);
    os << "revocationDate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (crlEntryExtensions))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "crlEntryExtensions ";
    os << *crlEntryExtensions;
  }
  else
  {
    Indent (os, indentG);
    os << "crlEntryExtensions ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CRLToSignSeqOfSeq::Print


AsnType *CRLToSignSeqOf::Clone() const
{
  return new CRLToSignSeqOf;
}

AsnType *CRLToSignSeqOf::Copy() const
{
  return new CRLToSignSeqOf (*this);
}

AsnLen CRLToSignSeqOf::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CRLToSignSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CRLToSignSeqOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-139);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

CRLToSignSeqOf::CRLToSignSeqOf (const CRLToSignSeqOf &)
{
  Asn1Error << "use of incompletely defined CRLToSignSeqOf::CRLToSignSeqOf (const CRLToSignSeqOf &)" << endl;
  abort();
}

CRLToSignSeqOf::~CRLToSignSeqOf()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &that)
#else // SNACC_DEEP_COPY
CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CRLToSignSeqOf &CRLToSignSeqOf::operator = (const CRLToSignSeqOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void CRLToSignSeqOf::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  CRLToSignSeqOf::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // CRLToSignSeqOf::SetCurrElmt


unsigned long int  CRLToSignSeqOf::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // CRLToSignSeqOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
CRLToSignSeqOfSeq *CRLToSignSeqOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new CRLToSignSeqOfSeq;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CRLToSignSeqOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
CRLToSignSeqOfSeq  *CRLToSignSeqOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CRLToSignSeqOf::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
CRLToSignSeqOfSeq  *CRLToSignSeqOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CRLToSignSeqOf::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CRLToSignSeqOfSeq *CRLToSignSeqOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CRLToSignSeqOf::InsertAfter


CRLToSignSeqOf  &CRLToSignSeqOf::AppendCopy (CRLToSignSeqOfSeq &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


CRLToSignSeqOf  &CRLToSignSeqOf::PrependCopy (CRLToSignSeqOfSeq &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // CRLToSignSeqOf::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
CRLToSignSeqOf &CRLToSignSeqOf::InsertBeforeAndCopy (CRLToSignSeqOfSeq &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // CRLToSignSeqOf::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CRLToSignSeqOf  &CRLToSignSeqOf::InsertAfterAndCopy (CRLToSignSeqOfSeq &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CRLToSignSeqOfSeq;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // CRLToSignSeqOf::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void CRLToSignSeqOf::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen CRLToSignSeqOf::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // CRLToSignSeqOf::BEncContent


void  CRLToSignSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    CRLToSignSeqOfSeq *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-140);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // CRLToSignSeqOf::BDecContent


CertificateToSign::CertificateToSign()
{
  version = NULL;
#if TCL
  signature = new AlgorithmIdentifier;
#else
  signature = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  issuer = new Name;
#else
  issuer = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  validity = new Validity;
#else
  validity = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  subject = new Name;
#else
  subject = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  subjectPublicKeyInfo = new SubjectPublicKeyInfo;
#else
  subjectPublicKeyInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  issuerUniqueIdentifier = NULL;
  subjectUniqueIdentifier = NULL;
  extensions = NULL;
}

CertificateToSign::CertificateToSign (const CertificateToSign &)
{
  Asn1Error << "use of incompletely defined CertificateToSign::CertificateToSign (const CertificateToSign &)" << endl;
  abort();
}

CertificateToSign::~CertificateToSign()
{
  delete version;
  delete signature;
  delete issuer;
  delete validity;
  delete subject;
  delete subjectPublicKeyInfo;
  delete issuerUniqueIdentifier;
  delete subjectUniqueIdentifier;
  delete extensions;
}

AsnType *CertificateToSign::Clone() const
{
  return new CertificateToSign;
}

AsnType *CertificateToSign::Copy() const
{
  return new CertificateToSign (*this);
}

#if SNACC_DEEP_COPY
CertificateToSign &CertificateToSign::operator = (const CertificateToSign &that)
#else // SNACC_DEEP_COPY
CertificateToSign &CertificateToSign::operator = (const CertificateToSign &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.version)
    {
      if (!version)
        version = new Version;
      *version = *that.version;
    }
    else
    {
      delete version;
      version = NULL;
    }
    serialNumber = that.serialNumber;
    if (that.signature)
    {
      if (!signature)
        signature = new AlgorithmIdentifier;
      *signature = *that.signature;
    }
    else
    {
      delete signature;
      signature = NULL;
    }
    if (that.issuer)
    {
      if (!issuer)
        issuer = new Name;
      *issuer = *that.issuer;
    }
    else
    {
      delete issuer;
      issuer = NULL;
    }
    if (that.validity)
    {
      if (!validity)
        validity = new Validity;
      *validity = *that.validity;
    }
    else
    {
      delete validity;
      validity = NULL;
    }
    if (that.subject)
    {
      if (!subject)
        subject = new Name;
      *subject = *that.subject;
    }
    else
    {
      delete subject;
      subject = NULL;
    }
    if (that.subjectPublicKeyInfo)
    {
      if (!subjectPublicKeyInfo)
        subjectPublicKeyInfo = new SubjectPublicKeyInfo;
      *subjectPublicKeyInfo = *that.subjectPublicKeyInfo;
    }
    else
    {
      delete subjectPublicKeyInfo;
      subjectPublicKeyInfo = NULL;
    }
    if (that.issuerUniqueIdentifier)
    {
      if (!issuerUniqueIdentifier)
        issuerUniqueIdentifier = new UniqueIdentifier;
      *issuerUniqueIdentifier = *that.issuerUniqueIdentifier;
    }
    else
    {
      delete issuerUniqueIdentifier;
      issuerUniqueIdentifier = NULL;
    }
    if (that.subjectUniqueIdentifier)
    {
      if (!subjectUniqueIdentifier)
        subjectUniqueIdentifier = new UniqueIdentifier;
      *subjectUniqueIdentifier = *that.subjectUniqueIdentifier;
    }
    else
    {
      delete subjectUniqueIdentifier;
      subjectUniqueIdentifier = NULL;
    }
    if (that.extensions)
    {
      if (!extensions)
        extensions = new Extensions;
      *extensions = *that.extensions;
    }
    else
    {
      delete extensions;
      extensions = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificateToSign &CertificateToSign::operator = (const CertificateToSign &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CertificateToSign::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (extensions))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = extensions->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 3);
    totalLen += l;
  }

  if (NOT_NULL (subjectUniqueIdentifier))
  {
    l = subjectUniqueIdentifier->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 2);
    totalLen += l;
  }

  if (NOT_NULL (issuerUniqueIdentifier))
  {
    l = issuerUniqueIdentifier->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 1);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = subjectPublicKeyInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = subject->BEncContent (b);
    totalLen += l;

      BEncEocIfNec (b);
    l = validity->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = issuer->BEncContent (b);
    totalLen += l;

      BEncEocIfNec (b);
    l = signature->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = serialNumber.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (version))
  {
      BEncEocIfNec (b);
    l = version->BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  return totalLen;
} // CertificateToSign::BEncContent


void CertificateToSign::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-141);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    version = new Version;
    version->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-142);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signature = new AlgorithmIdentifier;
    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-143);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuer = new Name;
    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-144);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    validity = new Validity;
    validity->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-145);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subject = new Name;
    subject->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-146);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subjectPublicKeyInfo = new SubjectPublicKeyInfo;
    subjectPublicKeyInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-147);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 1))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuerUniqueIdentifier = new UniqueIdentifier;
    issuerUniqueIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 2))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subjectUniqueIdentifier = new UniqueIdentifier;
    subjectUniqueIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-148);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    extensions = new Extensions;
    extensions->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-149);
  }
  else
    return;
} // CertificateToSign::BDecContent

AsnLen CertificateToSign::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CertificateToSign::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CertificateToSign::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-150);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CertificateToSign::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (version))
  {
    Indent (os, indentG);
    os << "version ";
    os << *version;
  }
  else
  {
    Indent (os, indentG);
    os << "version ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "serialNumber ";
    os << serialNumber;
    os << "," << endl;
  }

  if (NOT_NULL (signature))
  {
    Indent (os, indentG);
    os << "signature ";
    os << *signature;
  }
  else
  {
    Indent (os, indentG);
    os << "signature ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (issuer))
  {
    Indent (os, indentG);
    os << "issuer ";
    os << *issuer;
  }
  else
  {
    Indent (os, indentG);
    os << "issuer ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (validity))
  {
    Indent (os, indentG);
    os << "validity ";
    os << *validity;
  }
  else
  {
    Indent (os, indentG);
    os << "validity ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (subject))
  {
    Indent (os, indentG);
    os << "subject ";
    os << *subject;
  }
  else
  {
    Indent (os, indentG);
    os << "subject ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (subjectPublicKeyInfo))
  {
    Indent (os, indentG);
    os << "subjectPublicKeyInfo ";
    os << *subjectPublicKeyInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "subjectPublicKeyInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (issuerUniqueIdentifier))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "issuerUniqueIdentifier ";
    os << *issuerUniqueIdentifier;
  }
  else
  {
    Indent (os, indentG);
    os << "issuerUniqueIdentifier ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (subjectUniqueIdentifier))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "subjectUniqueIdentifier ";
    os << *subjectUniqueIdentifier;
  }
  else
  {
    Indent (os, indentG);
    os << "subjectUniqueIdentifier ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (extensions))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "extensions ";
    os << *extensions;
  }
  else
  {
    Indent (os, indentG);
    os << "extensions ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CertificateToSign::Print


CRLToSign::CRLToSign()
{
  version = NULL;
#if TCL
  signature = new AlgorithmIdentifier;
#else
  signature = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  issuer = new Name;
#else
  issuer = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  thisUpdate = new Time;
#else
  thisUpdate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  nextUpdate = NULL;
  revokedCertificates = NULL;
  crlExtensions = NULL;
}

CRLToSign::CRLToSign (const CRLToSign &)
{
  Asn1Error << "use of incompletely defined CRLToSign::CRLToSign (const CRLToSign &)" << endl;
  abort();
}

CRLToSign::~CRLToSign()
{
  delete version;
  delete signature;
  delete issuer;
  delete thisUpdate;
  delete nextUpdate;
  delete revokedCertificates;
  delete crlExtensions;
}

AsnType *CRLToSign::Clone() const
{
  return new CRLToSign;
}

AsnType *CRLToSign::Copy() const
{
  return new CRLToSign (*this);
}

#if SNACC_DEEP_COPY
CRLToSign &CRLToSign::operator = (const CRLToSign &that)
#else // SNACC_DEEP_COPY
CRLToSign &CRLToSign::operator = (const CRLToSign &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.version)
    {
      if (!version)
        version = new Version;
      *version = *that.version;
    }
    else
    {
      delete version;
      version = NULL;
    }
    if (that.signature)
    {
      if (!signature)
        signature = new AlgorithmIdentifier;
      *signature = *that.signature;
    }
    else
    {
      delete signature;
      signature = NULL;
    }
    if (that.issuer)
    {
      if (!issuer)
        issuer = new Name;
      *issuer = *that.issuer;
    }
    else
    {
      delete issuer;
      issuer = NULL;
    }
    if (that.thisUpdate)
    {
      if (!thisUpdate)
        thisUpdate = new Time;
      *thisUpdate = *that.thisUpdate;
    }
    else
    {
      delete thisUpdate;
      thisUpdate = NULL;
    }
    if (that.nextUpdate)
    {
      if (!nextUpdate)
        nextUpdate = new Time;
      *nextUpdate = *that.nextUpdate;
    }
    else
    {
      delete nextUpdate;
      nextUpdate = NULL;
    }
    if (that.revokedCertificates)
    {
      if (!revokedCertificates)
        revokedCertificates = new CRLToSignSeqOf;
      *revokedCertificates = *that.revokedCertificates;
    }
    else
    {
      delete revokedCertificates;
      revokedCertificates = NULL;
    }
    if (that.crlExtensions)
    {
      if (!crlExtensions)
        crlExtensions = new Extensions;
      *crlExtensions = *that.crlExtensions;
    }
    else
    {
      delete crlExtensions;
      crlExtensions = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CRLToSign &CRLToSign::operator = (const CRLToSign &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CRLToSign::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (crlExtensions))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = crlExtensions->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  if (NOT_NULL (revokedCertificates))
  {
      BEncEocIfNec (b);
    l = revokedCertificates->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

  if (NOT_NULL (nextUpdate))
  {
    l = nextUpdate->BEncContent (b);
    totalLen += l;
  }

    l = thisUpdate->BEncContent (b);
    totalLen += l;

    l = issuer->BEncContent (b);
    totalLen += l;

      BEncEocIfNec (b);
    l = signature->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (version))
  {
    l = version->BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;
  }

  return totalLen;
} // CRLToSign::BEncContent


void CRLToSign::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version = new Version;
    version->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signature = new AlgorithmIdentifier;
    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-151);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuer = new Name;
    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-152);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    thisUpdate = new Time;
    thisUpdate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-153);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, UTCTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    nextUpdate = new Time;
    nextUpdate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    revokedCertificates = new CRLToSignSeqOf;
    revokedCertificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-154);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    crlExtensions = new Extensions;
    crlExtensions->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-155);
  }
  else
    return;
} // CRLToSign::BDecContent

AsnLen CRLToSign::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CRLToSign::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CRLToSign::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-156);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CRLToSign::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (version))
  {
    Indent (os, indentG);
    os << "version ";
    os << *version;
  }
  else
  {
    Indent (os, indentG);
    os << "version ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (signature))
  {
    Indent (os, indentG);
    os << "signature ";
    os << *signature;
  }
  else
  {
    Indent (os, indentG);
    os << "signature ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (issuer))
  {
    Indent (os, indentG);
    os << "issuer ";
    os << *issuer;
  }
  else
  {
    Indent (os, indentG);
    os << "issuer ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (thisUpdate))
  {
    Indent (os, indentG);
    os << "thisUpdate ";
    os << *thisUpdate;
  }
  else
  {
    Indent (os, indentG);
    os << "thisUpdate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (nextUpdate))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "nextUpdate ";
    os << *nextUpdate;
  }
  else
  {
    Indent (os, indentG);
    os << "nextUpdate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (revokedCertificates))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "revokedCertificates ";
    os << *revokedCertificates;
  }
  else
  {
    Indent (os, indentG);
    os << "revokedCertificates ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (crlExtensions))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "crlExtensions ";
    os << *crlExtensions;
  }
  else
  {
    Indent (os, indentG);
    os << "crlExtensions ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CRLToSign::Print


AttributeCertificateInfo::AttributeCertificateInfo()
{
  version = NULL;
#if TCL
  subject = new AttributeCertificateInfoChoice;
#else
  subject = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  signature = new AlgorithmIdentifier;
#else
  signature = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  attCertValidityPeriod = new AttCertValidityPeriod;
#else
  attCertValidityPeriod = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  issuerUniqueID = NULL;
  extensions = NULL;
}

AttributeCertificateInfo::AttributeCertificateInfo (const AttributeCertificateInfo &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateInfo::AttributeCertificateInfo (const AttributeCertificateInfo &)" << endl;
  abort();
}

AttributeCertificateInfo::~AttributeCertificateInfo()
{
  delete version;
  delete subject;
  delete signature;
  delete attCertValidityPeriod;
  delete issuerUniqueID;
  delete extensions;
}

AsnType *AttributeCertificateInfo::Clone() const
{
  return new AttributeCertificateInfo;
}

AsnType *AttributeCertificateInfo::Copy() const
{
  return new AttributeCertificateInfo (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &that)
#else // SNACC_DEEP_COPY
AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.version)
    {
      if (!version)
        version = new Version;
      *version = *that.version;
    }
    else
    {
      delete version;
      version = NULL;
    }
    if (that.subject)
    {
      if (!subject)
        subject = new AttributeCertificateInfoChoice;
      *subject = *that.subject;
    }
    else
    {
      delete subject;
      subject = NULL;
    }
    issuer = that.issuer;
    if (that.signature)
    {
      if (!signature)
        signature = new AlgorithmIdentifier;
      *signature = *that.signature;
    }
    else
    {
      delete signature;
      signature = NULL;
    }
    serialNumber = that.serialNumber;
    if (that.attCertValidityPeriod)
    {
      if (!attCertValidityPeriod)
        attCertValidityPeriod = new AttCertValidityPeriod;
      *attCertValidityPeriod = *that.attCertValidityPeriod;
    }
    else
    {
      delete attCertValidityPeriod;
      attCertValidityPeriod = NULL;
    }
    attributes = that.attributes;
    if (that.issuerUniqueID)
    {
      if (!issuerUniqueID)
        issuerUniqueID = new UniqueIdentifier;
      *issuerUniqueID = *that.issuerUniqueID;
    }
    else
    {
      delete issuerUniqueID;
      issuerUniqueID = NULL;
    }
    if (that.extensions)
    {
      if (!extensions)
        extensions = new Extensions;
      *extensions = *that.extensions;
    }
    else
    {
      delete extensions;
      extensions = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateInfo &AttributeCertificateInfo::operator = (const AttributeCertificateInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificateInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (extensions))
  {
      BEncEocIfNec (b);
    l = extensions->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

  if (NOT_NULL (issuerUniqueID))
  {
    l = issuerUniqueID->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = attributes.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = attCertValidityPeriod->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = serialNumber.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = signature->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = issuer.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = subject->BEncContent (b);
    totalLen += l;

  if (NOT_NULL (version))
  {
    l = version->BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;
  }

  return totalLen;
} // AttributeCertificateInfo::BEncContent


void AttributeCertificateInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version = new Version;
    version->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subject = new AttributeCertificateInfoChoice;
    subject->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-157);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuer.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-158);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signature = new AlgorithmIdentifier;
    signature->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-159);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-160);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attCertValidityPeriod = new AttCertValidityPeriod;
    attCertValidityPeriod->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-161);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attributes.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-162);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuerUniqueID = new UniqueIdentifier;
    issuerUniqueID->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    extensions = new Extensions;
    extensions->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-163);
  }
  else
    return;
} // AttributeCertificateInfo::BDecContent

AsnLen AttributeCertificateInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificateInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificateInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-164);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AttributeCertificateInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (version))
  {
    Indent (os, indentG);
    os << "version ";
    os << *version;
  }
  else
  {
    Indent (os, indentG);
    os << "version ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (subject))
  {
    Indent (os, indentG);
    os << "subject ";
    os << *subject;
  }
  else
  {
    Indent (os, indentG);
    os << "subject ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "issuer ";
    os << issuer;
    os << "," << endl;
  }

  if (NOT_NULL (signature))
  {
    Indent (os, indentG);
    os << "signature ";
    os << *signature;
  }
  else
  {
    Indent (os, indentG);
    os << "signature ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "serialNumber ";
    os << serialNumber;
    os << "," << endl;
  }

  if (NOT_NULL (attCertValidityPeriod))
  {
    Indent (os, indentG);
    os << "attCertValidityPeriod ";
    os << *attCertValidityPeriod;
  }
  else
  {
    Indent (os, indentG);
    os << "attCertValidityPeriod ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "attributes ";
    os << attributes;
    os << "," << endl;
  }

  if (NOT_NULL (issuerUniqueID))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "issuerUniqueID ";
    os << *issuerUniqueID;
  }
  else
  {
    Indent (os, indentG);
    os << "issuerUniqueID ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (extensions))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "extensions ";
    os << *extensions;
  }
  else
  {
    Indent (os, indentG);
    os << "extensions ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AttributeCertificateInfo::Print


Certificate::Certificate()
{
#if TCL
  certificateToSign = new CertificateToSign;
#else
  certificateToSign = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  algorithmIdentifier = new AlgorithmIdentifier;
#else
  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

Certificate::Certificate (const Certificate &)
{
  Asn1Error << "use of incompletely defined Certificate::Certificate (const Certificate &)" << endl;
  abort();
}

Certificate::~Certificate()
{
  delete certificateToSign;
  delete algorithmIdentifier;
}

AsnType *Certificate::Clone() const
{
  return new Certificate;
}

AsnType *Certificate::Copy() const
{
  return new Certificate (*this);
}

#if SNACC_DEEP_COPY
Certificate &Certificate::operator = (const Certificate &that)
#else // SNACC_DEEP_COPY
Certificate &Certificate::operator = (const Certificate &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.certificateToSign)
    {
      if (!certificateToSign)
        certificateToSign = new CertificateToSign;
      *certificateToSign = *that.certificateToSign;
    }
    else
    {
      delete certificateToSign;
      certificateToSign = NULL;
    }
    if (that.algorithmIdentifier)
    {
      if (!algorithmIdentifier)
        algorithmIdentifier = new AlgorithmIdentifier;
      *algorithmIdentifier = *that.algorithmIdentifier;
    }
    else
    {
      delete algorithmIdentifier;
      algorithmIdentifier = NULL;
    }
    signatureValue = that.signatureValue;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Certificate &Certificate::operator = (const Certificate &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
Certificate::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = signatureValue.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = algorithmIdentifier->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = certificateToSign->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // Certificate::BEncContent


void Certificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    certificateToSign = new CertificateToSign;
    certificateToSign->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-165);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithmIdentifier = new AlgorithmIdentifier;
    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-166);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-167);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-168);
  }
  else
    return;
} // Certificate::BDecContent

AsnLen Certificate::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void Certificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "Certificate::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-169);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void Certificate::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (certificateToSign))
  {
    Indent (os, indentG);
    os << "certificateToSign ";
    os << *certificateToSign;
  }
  else
  {
    Indent (os, indentG);
    os << "certificateToSign ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (algorithmIdentifier))
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << *algorithmIdentifier;
  }
  else
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signatureValue ";
    os << signatureValue;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // Certificate::Print


AsnType *CrossCertificates::Clone() const
{
  return new CrossCertificates;
}

AsnType *CrossCertificates::Copy() const
{
  return new CrossCertificates (*this);
}

AsnLen CrossCertificates::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void CrossCertificates::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "CrossCertificates::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-170);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

CrossCertificates::CrossCertificates (const CrossCertificates &)
{
  Asn1Error << "use of incompletely defined CrossCertificates::CrossCertificates (const CrossCertificates &)" << endl;
  abort();
}

CrossCertificates::~CrossCertificates()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
CrossCertificates &CrossCertificates::operator = (const CrossCertificates &that)
#else // SNACC_DEEP_COPY
CrossCertificates &CrossCertificates::operator = (const CrossCertificates &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CrossCertificates &CrossCertificates::operator = (const CrossCertificates &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void CrossCertificates::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  CrossCertificates::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // CrossCertificates::SetCurrElmt


unsigned long int  CrossCertificates::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // CrossCertificates::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
Certificate *CrossCertificates::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new Certificate;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CrossCertificates::Append


// alloc new list elmt, put at begining of list
//  and return the component type
Certificate  *CrossCertificates::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CrossCertificates::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
Certificate  *CrossCertificates::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CrossCertificates::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
Certificate *CrossCertificates::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CrossCertificates::InsertAfter


CrossCertificates  &CrossCertificates::AppendCopy (Certificate &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


CrossCertificates  &CrossCertificates::PrependCopy (Certificate &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // CrossCertificates::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
CrossCertificates &CrossCertificates::InsertBeforeAndCopy (Certificate &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // CrossCertificates::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CrossCertificates  &CrossCertificates::InsertAfterAndCopy (Certificate &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new Certificate;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // CrossCertificates::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void CrossCertificates::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen CrossCertificates::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
      BEncEocIfNec (b);
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncConsLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // CrossCertificates::BEncContent


void  CrossCertificates::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    Certificate *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-171);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // CrossCertificates::BDecContent


CertificatePair::CertificatePair()
{
  forward = NULL;
  reverse = NULL;
}

CertificatePair::CertificatePair (const CertificatePair &)
{
  Asn1Error << "use of incompletely defined CertificatePair::CertificatePair (const CertificatePair &)" << endl;
  abort();
}

CertificatePair::~CertificatePair()
{
  delete forward;
  delete reverse;
}

AsnType *CertificatePair::Clone() const
{
  return new CertificatePair;
}

AsnType *CertificatePair::Copy() const
{
  return new CertificatePair (*this);
}

#if SNACC_DEEP_COPY
CertificatePair &CertificatePair::operator = (const CertificatePair &that)
#else // SNACC_DEEP_COPY
CertificatePair &CertificatePair::operator = (const CertificatePair &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.forward)
    {
      if (!forward)
        forward = new Certificate;
      *forward = *that.forward;
    }
    else
    {
      delete forward;
      forward = NULL;
    }
    if (that.reverse)
    {
      if (!reverse)
        reverse = new Certificate;
      *reverse = *that.reverse;
    }
    else
    {
      delete reverse;
      reverse = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificatePair &CertificatePair::operator = (const CertificatePair &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CertificatePair::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (reverse))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = reverse->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

  if (NOT_NULL (forward))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = forward->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  return totalLen;
} // CertificatePair::BEncContent


void CertificatePair::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  if (elmtLen0 == 0)
    return;
  else
  {
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
    {
      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
      bytesDecoded += seqBytesDecoded;
      return;
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-172);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    forward = new Certificate;
    forward->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-173);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    reverse = new Certificate;
    reverse->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-174);
  }
  else
    return;
} // CertificatePair::BDecContent

AsnLen CertificatePair::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CertificatePair::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CertificatePair::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-175);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CertificatePair::Print (ostream &os) const
{
#ifndef NDEBUG
  int nonePrinted = true;
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (forward))
  {
    nonePrinted = false;
    Indent (os, indentG);
    os << "forward ";
    os << *forward;
  }
  else
  {
    Indent (os, indentG);
    os << "forward ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (reverse))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "reverse ";
    os << *reverse;
  }
  else
  {
    Indent (os, indentG);
    os << "reverse ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CertificatePair::Print


CertificateList::CertificateList()
{
#if TCL
  crlToSign = new CRLToSign;
#else
  crlToSign = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  algorithmIdentifier = new AlgorithmIdentifier;
#else
  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

CertificateList::CertificateList (const CertificateList &)
{
  Asn1Error << "use of incompletely defined CertificateList::CertificateList (const CertificateList &)" << endl;
  abort();
}

CertificateList::~CertificateList()
{
  delete crlToSign;
  delete algorithmIdentifier;
}

AsnType *CertificateList::Clone() const
{
  return new CertificateList;
}

AsnType *CertificateList::Copy() const
{
  return new CertificateList (*this);
}

#if SNACC_DEEP_COPY
CertificateList &CertificateList::operator = (const CertificateList &that)
#else // SNACC_DEEP_COPY
CertificateList &CertificateList::operator = (const CertificateList &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.crlToSign)
    {
      if (!crlToSign)
        crlToSign = new CRLToSign;
      *crlToSign = *that.crlToSign;
    }
    else
    {
      delete crlToSign;
      crlToSign = NULL;
    }
    if (that.algorithmIdentifier)
    {
      if (!algorithmIdentifier)
        algorithmIdentifier = new AlgorithmIdentifier;
      *algorithmIdentifier = *that.algorithmIdentifier;
    }
    else
    {
      delete algorithmIdentifier;
      algorithmIdentifier = NULL;
    }
    signatureValue = that.signatureValue;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificateList &CertificateList::operator = (const CertificateList &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CertificateList::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = signatureValue.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = algorithmIdentifier->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = crlToSign->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // CertificateList::BEncContent


void CertificateList::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    crlToSign = new CRLToSign;
    crlToSign->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-176);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithmIdentifier = new AlgorithmIdentifier;
    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-177);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-178);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-179);
  }
  else
    return;
} // CertificateList::BDecContent

AsnLen CertificateList::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CertificateList::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CertificateList::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-180);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CertificateList::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (crlToSign))
  {
    Indent (os, indentG);
    os << "crlToSign ";
    os << *crlToSign;
  }
  else
  {
    Indent (os, indentG);
    os << "crlToSign ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (algorithmIdentifier))
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << *algorithmIdentifier;
  }
  else
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signatureValue ";
    os << signatureValue;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CertificateList::Print


AttributeCertificate::AttributeCertificate()
{
#if TCL
  attributeCertificateInfo = new AttributeCertificateInfo;
#else
  attributeCertificateInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  algorithmIdentifier = new AlgorithmIdentifier;
#else
  algorithmIdentifier = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

AttributeCertificate::AttributeCertificate (const AttributeCertificate &)
{
  Asn1Error << "use of incompletely defined AttributeCertificate::AttributeCertificate (const AttributeCertificate &)" << endl;
  abort();
}

AttributeCertificate::~AttributeCertificate()
{
  delete attributeCertificateInfo;
  delete algorithmIdentifier;
}

AsnType *AttributeCertificate::Clone() const
{
  return new AttributeCertificate;
}

AsnType *AttributeCertificate::Copy() const
{
  return new AttributeCertificate (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &that)
#else // SNACC_DEEP_COPY
AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.attributeCertificateInfo)
    {
      if (!attributeCertificateInfo)
        attributeCertificateInfo = new AttributeCertificateInfo;
      *attributeCertificateInfo = *that.attributeCertificateInfo;
    }
    else
    {
      delete attributeCertificateInfo;
      attributeCertificateInfo = NULL;
    }
    if (that.algorithmIdentifier)
    {
      if (!algorithmIdentifier)
        algorithmIdentifier = new AlgorithmIdentifier;
      *algorithmIdentifier = *that.algorithmIdentifier;
    }
    else
    {
      delete algorithmIdentifier;
      algorithmIdentifier = NULL;
    }
    signatureValue = that.signatureValue;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificate &AttributeCertificate::operator = (const AttributeCertificate &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificate::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = signatureValue.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = algorithmIdentifier->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = attributeCertificateInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // AttributeCertificate::BEncContent


void AttributeCertificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attributeCertificateInfo = new AttributeCertificateInfo;
    attributeCertificateInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-181);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithmIdentifier = new AlgorithmIdentifier;
    algorithmIdentifier->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-182);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signatureValue.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-183);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-184);
  }
  else
    return;
} // AttributeCertificate::BDecContent

AsnLen AttributeCertificate::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificate::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-185);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AttributeCertificate::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (attributeCertificateInfo))
  {
    Indent (os, indentG);
    os << "attributeCertificateInfo ";
    os << *attributeCertificateInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "attributeCertificateInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (algorithmIdentifier))
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << *algorithmIdentifier;
  }
  else
  {
    Indent (os, indentG);
    os << "algorithmIdentifier ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signatureValue ";
    os << signatureValue;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AttributeCertificate::Print


AsnType *CertificationPathSeqOf::Clone() const
{
  return new CertificationPathSeqOf;
}

AsnType *CertificationPathSeqOf::Copy() const
{
  return new CertificationPathSeqOf (*this);
}

AsnLen CertificationPathSeqOf::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CertificationPathSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CertificationPathSeqOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-186);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

CertificationPathSeqOf::CertificationPathSeqOf (const CertificationPathSeqOf &)
{
  Asn1Error << "use of incompletely defined CertificationPathSeqOf::CertificationPathSeqOf (const CertificationPathSeqOf &)" << endl;
  abort();
}

CertificationPathSeqOf::~CertificationPathSeqOf()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &that)
#else // SNACC_DEEP_COPY
CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificationPathSeqOf &CertificationPathSeqOf::operator = (const CertificationPathSeqOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void CertificationPathSeqOf::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  CertificationPathSeqOf::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // CertificationPathSeqOf::SetCurrElmt


unsigned long int  CertificationPathSeqOf::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // CertificationPathSeqOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
CertificatePair *CertificationPathSeqOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new CertificatePair;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificationPathSeqOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
CertificatePair  *CertificationPathSeqOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificationPathSeqOf::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificatePair  *CertificationPathSeqOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificationPathSeqOf::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificatePair *CertificationPathSeqOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificationPathSeqOf::InsertAfter


CertificationPathSeqOf  &CertificationPathSeqOf::AppendCopy (CertificatePair &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


CertificationPathSeqOf  &CertificationPathSeqOf::PrependCopy (CertificatePair &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // CertificationPathSeqOf::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificationPathSeqOf &CertificationPathSeqOf::InsertBeforeAndCopy (CertificatePair &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // CertificationPathSeqOf::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificationPathSeqOf  &CertificationPathSeqOf::InsertAfterAndCopy (CertificatePair &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificatePair;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // CertificationPathSeqOf::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void CertificationPathSeqOf::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen CertificationPathSeqOf::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // CertificationPathSeqOf::BEncContent


void  CertificationPathSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    CertificatePair *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-187);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // CertificationPathSeqOf::BDecContent


AsnType *ForwardCertificationPath::Clone() const
{
  return new ForwardCertificationPath;
}

AsnType *ForwardCertificationPath::Copy() const
{
  return new ForwardCertificationPath (*this);
}

AsnLen ForwardCertificationPath::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void ForwardCertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "ForwardCertificationPath::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-188);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

ForwardCertificationPath::ForwardCertificationPath (const ForwardCertificationPath &)
{
  Asn1Error << "use of incompletely defined ForwardCertificationPath::ForwardCertificationPath (const ForwardCertificationPath &)" << endl;
  abort();
}

ForwardCertificationPath::~ForwardCertificationPath()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &that)
#else // SNACC_DEEP_COPY
ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ForwardCertificationPath &ForwardCertificationPath::operator = (const ForwardCertificationPath &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void ForwardCertificationPath::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  ForwardCertificationPath::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // ForwardCertificationPath::SetCurrElmt


unsigned long int  ForwardCertificationPath::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // ForwardCertificationPath::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
CrossCertificates *ForwardCertificationPath::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new CrossCertificates;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // ForwardCertificationPath::Append


// alloc new list elmt, put at begining of list
//  and return the component type
CrossCertificates  *ForwardCertificationPath::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // ForwardCertificationPath::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
CrossCertificates  *ForwardCertificationPath::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // ForwardCertificationPath::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CrossCertificates *ForwardCertificationPath::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // ForwardCertificationPath::InsertAfter


ForwardCertificationPath  &ForwardCertificationPath::AppendCopy (CrossCertificates &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


ForwardCertificationPath  &ForwardCertificationPath::PrependCopy (CrossCertificates &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // ForwardCertificationPath::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
ForwardCertificationPath &ForwardCertificationPath::InsertBeforeAndCopy (CrossCertificates &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // ForwardCertificationPath::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
ForwardCertificationPath  &ForwardCertificationPath::InsertAfterAndCopy (CrossCertificates &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CrossCertificates;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // ForwardCertificationPath::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void ForwardCertificationPath::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen ForwardCertificationPath::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // ForwardCertificationPath::BEncContent


void  ForwardCertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    CrossCertificates *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-189);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // ForwardCertificationPath::BDecContent


ACPathData::ACPathData()
{
  certificate = NULL;
  attributeCertificate = NULL;
}

ACPathData::ACPathData (const ACPathData &)
{
  Asn1Error << "use of incompletely defined ACPathData::ACPathData (const ACPathData &)" << endl;
  abort();
}

ACPathData::~ACPathData()
{
  delete certificate;
  delete attributeCertificate;
}

AsnType *ACPathData::Clone() const
{
  return new ACPathData;
}

AsnType *ACPathData::Copy() const
{
  return new ACPathData (*this);
}

#if SNACC_DEEP_COPY
ACPathData &ACPathData::operator = (const ACPathData &that)
#else // SNACC_DEEP_COPY
ACPathData &ACPathData::operator = (const ACPathData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.certificate)
    {
      if (!certificate)
        certificate = new Certificate;
      *certificate = *that.certificate;
    }
    else
    {
      delete certificate;
      certificate = NULL;
    }
    if (that.attributeCertificate)
    {
      if (!attributeCertificate)
        attributeCertificate = new AttributeCertificate;
      *attributeCertificate = *that.attributeCertificate;
    }
    else
    {
      delete attributeCertificate;
      attributeCertificate = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ACPathData &ACPathData::operator = (const ACPathData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
ACPathData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (attributeCertificate))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = attributeCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

  if (NOT_NULL (certificate))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = certificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  return totalLen;
} // ACPathData::BEncContent


void ACPathData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  if (elmtLen0 == 0)
    return;
  else
  {
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
    {
      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
      bytesDecoded += seqBytesDecoded;
      return;
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-190);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    certificate = new Certificate;
    certificate->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-191);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    attributeCertificate = new AttributeCertificate;
    attributeCertificate->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-192);
  }
  else
    return;
} // ACPathData::BDecContent

AsnLen ACPathData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void ACPathData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "ACPathData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-193);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void ACPathData::Print (ostream &os) const
{
#ifndef NDEBUG
  int nonePrinted = true;
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (certificate))
  {
    nonePrinted = false;
    Indent (os, indentG);
    os << "certificate ";
    os << *certificate;
  }
  else
  {
    Indent (os, indentG);
    os << "certificate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (attributeCertificate))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "attributeCertificate ";
    os << *attributeCertificate;
  }
  else
  {
    Indent (os, indentG);
    os << "attributeCertificate ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // ACPathData::Print


AsnType *AttributeCertificationPathSeqOf::Clone() const
{
  return new AttributeCertificationPathSeqOf;
}

AsnType *AttributeCertificationPathSeqOf::Copy() const
{
  return new AttributeCertificationPathSeqOf (*this);
}

AsnLen AttributeCertificationPathSeqOf::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificationPathSeqOf::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificationPathSeqOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-194);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

AttributeCertificationPathSeqOf::AttributeCertificationPathSeqOf (const AttributeCertificationPathSeqOf &)
{
  Asn1Error << "use of incompletely defined AttributeCertificationPathSeqOf::AttributeCertificationPathSeqOf (const AttributeCertificationPathSeqOf &)" << endl;
  abort();
}

AttributeCertificationPathSeqOf::~AttributeCertificationPathSeqOf()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &that)
#else // SNACC_DEEP_COPY
AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::operator = (const AttributeCertificationPathSeqOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeCertificationPathSeqOf::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  AttributeCertificationPathSeqOf::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // AttributeCertificationPathSeqOf::SetCurrElmt


unsigned long int  AttributeCertificationPathSeqOf::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // AttributeCertificationPathSeqOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
ACPathData *AttributeCertificationPathSeqOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new ACPathData;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificationPathSeqOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
ACPathData  *AttributeCertificationPathSeqOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificationPathSeqOf::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
ACPathData  *AttributeCertificationPathSeqOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificationPathSeqOf::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
ACPathData *AttributeCertificationPathSeqOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // AttributeCertificationPathSeqOf::InsertAfter


AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::AppendCopy (ACPathData &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::PrependCopy (ACPathData &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificationPathSeqOf::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
AttributeCertificationPathSeqOf &AttributeCertificationPathSeqOf::InsertBeforeAndCopy (ACPathData &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificationPathSeqOf::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
AttributeCertificationPathSeqOf  &AttributeCertificationPathSeqOf::InsertAfterAndCopy (ACPathData &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new ACPathData;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // AttributeCertificationPathSeqOf::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void AttributeCertificationPathSeqOf::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen AttributeCertificationPathSeqOf::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // AttributeCertificationPathSeqOf::BEncContent


void  AttributeCertificationPathSeqOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    ACPathData *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-195);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // AttributeCertificationPathSeqOf::BDecContent


Certificates::Certificates()
{
#if TCL
  userCertificate = new Certificate;
#else
  userCertificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  certificationPath = NULL;
}

Certificates::Certificates (const Certificates &)
{
  Asn1Error << "use of incompletely defined Certificates::Certificates (const Certificates &)" << endl;
  abort();
}

Certificates::~Certificates()
{
  delete userCertificate;
  delete certificationPath;
}

AsnType *Certificates::Clone() const
{
  return new Certificates;
}

AsnType *Certificates::Copy() const
{
  return new Certificates (*this);
}

#if SNACC_DEEP_COPY
Certificates &Certificates::operator = (const Certificates &that)
#else // SNACC_DEEP_COPY
Certificates &Certificates::operator = (const Certificates &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.userCertificate)
    {
      if (!userCertificate)
        userCertificate = new Certificate;
      *userCertificate = *that.userCertificate;
    }
    else
    {
      delete userCertificate;
      userCertificate = NULL;
    }
    if (that.certificationPath)
    {
      if (!certificationPath)
        certificationPath = new ForwardCertificationPath;
      *certificationPath = *that.certificationPath;
    }
    else
    {
      delete certificationPath;
      certificationPath = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined Certificates &Certificates::operator = (const Certificates &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
Certificates::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (certificationPath))
  {
      BEncEocIfNec (b);
    l = certificationPath->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = userCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // Certificates::BEncContent


void Certificates::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    userCertificate = new Certificate;
    userCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-196);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    certificationPath = new ForwardCertificationPath;
    certificationPath->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-197);
  }
  else
    return;
} // Certificates::BDecContent

AsnLen Certificates::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void Certificates::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "Certificates::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-198);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void Certificates::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (userCertificate))
  {
    Indent (os, indentG);
    os << "userCertificate ";
    os << *userCertificate;
  }
  else
  {
    Indent (os, indentG);
    os << "userCertificate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (certificationPath))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "certificationPath ";
    os << *certificationPath;
  }
  else
  {
    Indent (os, indentG);
    os << "certificationPath ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // Certificates::Print


CertificationPath::CertificationPath()
{
#if TCL
  userCertificate = new Certificate;
#else
  userCertificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  theCACertificates = NULL;
}

CertificationPath::CertificationPath (const CertificationPath &)
{
  Asn1Error << "use of incompletely defined CertificationPath::CertificationPath (const CertificationPath &)" << endl;
  abort();
}

CertificationPath::~CertificationPath()
{
  delete userCertificate;
  delete theCACertificates;
}

AsnType *CertificationPath::Clone() const
{
  return new CertificationPath;
}

AsnType *CertificationPath::Copy() const
{
  return new CertificationPath (*this);
}

#if SNACC_DEEP_COPY
CertificationPath &CertificationPath::operator = (const CertificationPath &that)
#else // SNACC_DEEP_COPY
CertificationPath &CertificationPath::operator = (const CertificationPath &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.userCertificate)
    {
      if (!userCertificate)
        userCertificate = new Certificate;
      *userCertificate = *that.userCertificate;
    }
    else
    {
      delete userCertificate;
      userCertificate = NULL;
    }
    if (that.theCACertificates)
    {
      if (!theCACertificates)
        theCACertificates = new CertificationPathSeqOf;
      *theCACertificates = *that.theCACertificates;
    }
    else
    {
      delete theCACertificates;
      theCACertificates = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificationPath &CertificationPath::operator = (const CertificationPath &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CertificationPath::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (theCACertificates))
  {
      BEncEocIfNec (b);
    l = theCACertificates->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = userCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // CertificationPath::BEncContent


void CertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    userCertificate = new Certificate;
    userCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-199);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    theCACertificates = new CertificationPathSeqOf;
    theCACertificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-200);
  }
  else
    return;
} // CertificationPath::BDecContent

AsnLen CertificationPath::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void CertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "CertificationPath::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-201);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void CertificationPath::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (userCertificate))
  {
    Indent (os, indentG);
    os << "userCertificate ";
    os << *userCertificate;
  }
  else
  {
    Indent (os, indentG);
    os << "userCertificate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (theCACertificates))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "theCACertificates ";
    os << *theCACertificates;
  }
  else
  {
    Indent (os, indentG);
    os << "theCACertificates ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // CertificationPath::Print


AttributeCertificationPath::AttributeCertificationPath()
{
#if TCL
  attributeCertificate = new AttributeCertificate;
#else
  attributeCertificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  acPath = NULL;
}

AttributeCertificationPath::AttributeCertificationPath (const AttributeCertificationPath &)
{
  Asn1Error << "use of incompletely defined AttributeCertificationPath::AttributeCertificationPath (const AttributeCertificationPath &)" << endl;
  abort();
}

AttributeCertificationPath::~AttributeCertificationPath()
{
  delete attributeCertificate;
  delete acPath;
}

AsnType *AttributeCertificationPath::Clone() const
{
  return new AttributeCertificationPath;
}

AsnType *AttributeCertificationPath::Copy() const
{
  return new AttributeCertificationPath (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &that)
#else // SNACC_DEEP_COPY
AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.attributeCertificate)
    {
      if (!attributeCertificate)
        attributeCertificate = new AttributeCertificate;
      *attributeCertificate = *that.attributeCertificate;
    }
    else
    {
      delete attributeCertificate;
      attributeCertificate = NULL;
    }
    if (that.acPath)
    {
      if (!acPath)
        acPath = new AttributeCertificationPathSeqOf;
      *acPath = *that.acPath;
    }
    else
    {
      delete acPath;
      acPath = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificationPath &AttributeCertificationPath::operator = (const AttributeCertificationPath &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificationPath::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (acPath))
  {
      BEncEocIfNec (b);
    l = acPath->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = attributeCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // AttributeCertificationPath::BEncContent


void AttributeCertificationPath::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attributeCertificate = new AttributeCertificate;
    attributeCertificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-202);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    acPath = new AttributeCertificationPathSeqOf;
    acPath->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-203);
  }
  else
    return;
} // AttributeCertificationPath::BDecContent

AsnLen AttributeCertificationPath::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificationPath::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificationPath::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-204);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AttributeCertificationPath::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (attributeCertificate))
  {
    Indent (os, indentG);
    os << "attributeCertificate ";
    os << *attributeCertificate;
  }
  else
  {
    Indent (os, indentG);
    os << "attributeCertificate ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (acPath))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "acPath ";
    os << *acPath;
  }
  else
  {
    Indent (os, indentG);
    os << "acPath ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AttributeCertificationPath::Print


AttributeCertificateAssertion::AttributeCertificateAssertion()
{
  subject = NULL;
  issuer = NULL;
  attCertValidity = NULL;
  attType = NULL;
}

AttributeCertificateAssertion::AttributeCertificateAssertion (const AttributeCertificateAssertion &)
{
  Asn1Error << "use of incompletely defined AttributeCertificateAssertion::AttributeCertificateAssertion (const AttributeCertificateAssertion &)" << endl;
  abort();
}

AttributeCertificateAssertion::~AttributeCertificateAssertion()
{
  delete subject;
  delete issuer;
  delete attCertValidity;
  delete attType;
}

AsnType *AttributeCertificateAssertion::Clone() const
{
  return new AttributeCertificateAssertion;
}

AsnType *AttributeCertificateAssertion::Copy() const
{
  return new AttributeCertificateAssertion (*this);
}

#if SNACC_DEEP_COPY
AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &that)
#else // SNACC_DEEP_COPY
AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.subject)
    {
      if (!subject)
        subject = new AttributeCertificateAssertionChoice;
      *subject = *that.subject;
    }
    else
    {
      delete subject;
      subject = NULL;
    }
    if (that.issuer)
    {
      if (!issuer)
        issuer = new Name;
      *issuer = *that.issuer;
    }
    else
    {
      delete issuer;
      issuer = NULL;
    }
    if (that.attCertValidity)
    {
      if (!attCertValidity)
        attCertValidity = new GeneralizedTime;
      *attCertValidity = *that.attCertValidity;
    }
    else
    {
      delete attCertValidity;
      attCertValidity = NULL;
    }
    if (that.attType)
    {
      if (!attType)
        attType = new AttributeCertificateAssertionSetOf;
      *attType = *that.attType;
    }
    else
    {
      delete attType;
      attType = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AttributeCertificateAssertion &AttributeCertificateAssertion::operator = (const AttributeCertificateAssertion &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AttributeCertificateAssertion::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (attType))
  {
      BEncEocIfNec (b);
      BEncEocIfNec (b);
    l = attType->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 3);
    totalLen += l;
  }

  if (NOT_NULL (attCertValidity))
  {
      BEncEocIfNec (b);
    l = attCertValidity->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 2);
    totalLen += l;
  }

  if (NOT_NULL (issuer))
  {
      BEncEocIfNec (b);
    l = issuer->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

  if (NOT_NULL (subject))
  {
      BEncEocIfNec (b);
    l = subject->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  return totalLen;
} // AttributeCertificateAssertion::BEncContent


void AttributeCertificateAssertion::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  if (elmtLen0 == 0)
    return;
  else
  {
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
    {
      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
      bytesDecoded += seqBytesDecoded;
      return;
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    subject = new AttributeCertificateAssertionChoice;
    subject->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    issuer = new Name;
    issuer->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
       && (tag1 != MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-205);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    attCertValidity = new GeneralizedTime;
    attCertValidity->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if (tag1 != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-206);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    attType = new AttributeCertificateAssertionSetOf;
    attType->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-207);
  }
  else
    return;
} // AttributeCertificateAssertion::BDecContent

AsnLen AttributeCertificateAssertion::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AttributeCertificateAssertion::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AttributeCertificateAssertion::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-208);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AttributeCertificateAssertion::Print (ostream &os) const
{
#ifndef NDEBUG
  int nonePrinted = true;
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (subject))
  {
    nonePrinted = false;
    Indent (os, indentG);
    os << "subject ";
    os << *subject;
  }
  else
  {
    Indent (os, indentG);
    os << "subject ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (issuer))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "issuer ";
    os << *issuer;
  }
  else
  {
    Indent (os, indentG);
    os << "issuer ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (attCertValidity))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "attCertValidity ";
    os << *attCertValidity;
  }
  else
  {
    Indent (os, indentG);
    os << "attCertValidity ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (attType))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "attType ";
    os << *attType;
  }
  else
  {
    Indent (os, indentG);
    os << "attType ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AttributeCertificateAssertion::Print


