//   NOTE: this is a machine generated file--editing not recommended
//
// sm_x501if.cpp - class member functions for ASN.1 module InformationFramework
//
//   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 *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Clone() const
{
  return new AttributeTypeAndDistinguishedValueSetOfSeqSetOf;
}

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

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

void AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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 << "AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-100);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &that)
#else // SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)
#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 AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOfSeqSetOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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  AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::SetCurrElmt


unsigned long int  AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
AsnAny *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new AsnAny;
    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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
AsnAny  *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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.
AsnAny  *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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.
AsnAny *AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfter


AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::AppendCopy (AsnAny &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    *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


AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::PrependCopy (AsnAny &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    *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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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.
AttributeTypeAndDistinguishedValueSetOfSeqSetOf &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertBeforeAndCopy (AsnAny &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    *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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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.
AttributeTypeAndDistinguishedValueSetOfSeqSetOf  &AttributeTypeAndDistinguishedValueSetOfSeqSetOf::InsertAfterAndCopy (AsnAny &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AsnAny;
    *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;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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 AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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 AttributeTypeAndDistinguishedValueSetOfSeqSetOf::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)
      {
        tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // AttributeTypeAndDistinguishedValueSetOfSeqSetOf::BEncContent


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

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        listElmt = Append();
        DEC_LOAD_ANYBUF(listElmt, b, listBytesDecoded, env);
    }

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


AttributeTypeAndDistinguishedValueSetOfSeq::AttributeTypeAndDistinguishedValueSetOfSeq()
{
  distingAttrValue = NULL;
}

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

AttributeTypeAndDistinguishedValueSetOfSeq::~AttributeTypeAndDistinguishedValueSetOfSeq()
{
  delete distingAttrValue;
}

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

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

#if SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOfSeq &AttributeTypeAndDistinguishedValueSetOfSeq::operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &that)
#else // SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOfSeq &AttributeTypeAndDistinguishedValueSetOfSeq::operator = (const AttributeTypeAndDistinguishedValueSetOfSeq &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.distingAttrValue)
    {
      if (!distingAttrValue)
        distingAttrValue = new AsnOid;
      *distingAttrValue = *that.distingAttrValue;
    }
    else
    {
      delete distingAttrValue;
      distingAttrValue = NULL;
    }
    contextList = that.contextList;
  }

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

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

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

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

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

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

  return totalLen;
} // AttributeTypeAndDistinguishedValueSetOfSeq::BEncContent


void AttributeTypeAndDistinguishedValueSetOfSeq::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);
    distingAttrValue = new AsnOid;
    distingAttrValue->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

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

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

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

void AttributeTypeAndDistinguishedValueSetOfSeq::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 << "AttributeTypeAndDistinguishedValueSetOfSeq::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-103);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

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

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


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

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

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

void AttributeTypeAndDistinguishedValueSetOf::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 << "AttributeTypeAndDistinguishedValueSetOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-104);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &that)
#else // SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &)
#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 AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::operator = (const AttributeTypeAndDistinguishedValueSetOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeTypeAndDistinguishedValueSetOf::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  AttributeTypeAndDistinguishedValueSetOf::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;
} // AttributeTypeAndDistinguishedValueSetOf::SetCurrElmt


unsigned long int  AttributeTypeAndDistinguishedValueSetOf::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;
} // AttributeTypeAndDistinguishedValueSetOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
AttributeTypeAndDistinguishedValueSetOfSeq *AttributeTypeAndDistinguishedValueSetOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new AttributeTypeAndDistinguishedValueSetOfSeq;
    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;
} // AttributeTypeAndDistinguishedValueSetOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
AttributeTypeAndDistinguishedValueSetOfSeq  *AttributeTypeAndDistinguishedValueSetOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    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;
} // AttributeTypeAndDistinguishedValueSetOf::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.
AttributeTypeAndDistinguishedValueSetOfSeq  *AttributeTypeAndDistinguishedValueSetOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    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;
} // AttributeTypeAndDistinguishedValueSetOf::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.
AttributeTypeAndDistinguishedValueSetOfSeq *AttributeTypeAndDistinguishedValueSetOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    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;
} // AttributeTypeAndDistinguishedValueSetOf::InsertAfter


AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::AppendCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    *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


AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::PrependCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    *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;
} // AttributeTypeAndDistinguishedValueSetOf::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.
AttributeTypeAndDistinguishedValueSetOf &AttributeTypeAndDistinguishedValueSetOf::InsertBeforeAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    *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;
} // AttributeTypeAndDistinguishedValueSetOf::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.
AttributeTypeAndDistinguishedValueSetOf  &AttributeTypeAndDistinguishedValueSetOf::InsertAfterAndCopy (AttributeTypeAndDistinguishedValueSetOfSeq &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValueSetOfSeq;
    *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;
} // AttributeTypeAndDistinguishedValueSetOf::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 AttributeTypeAndDistinguishedValueSetOf::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 AttributeTypeAndDistinguishedValueSetOf::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;
} // AttributeTypeAndDistinguishedValueSetOf::BEncContent


void  AttributeTypeAndDistinguishedValueSetOf::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    AttributeTypeAndDistinguishedValueSetOfSeq *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(-105);
        }

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

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


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

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

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

void AttributeSetOf::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 << "AttributeSetOf::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-106);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &that)
#else // SNACC_DEEP_COPY
AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &)
#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 AttributeSetOf &AttributeSetOf::operator = (const AttributeSetOf &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void AttributeSetOf::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  AttributeSetOf::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;
} // AttributeSetOf::SetCurrElmt


unsigned long int  AttributeSetOf::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;
} // AttributeSetOf::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
AttributeValue *AttributeSetOf::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new AttributeValue;
    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;
} // AttributeSetOf::Append


// alloc new list elmt, put at begining of list
//  and return the component type
AttributeValue  *AttributeSetOf::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    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;
} // AttributeSetOf::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.
AttributeValue  *AttributeSetOf::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    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;
} // AttributeSetOf::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.
AttributeValue *AttributeSetOf::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    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;
} // AttributeSetOf::InsertAfter


AttributeSetOf  &AttributeSetOf::AppendCopy (AttributeValue &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    *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


AttributeSetOf  &AttributeSetOf::PrependCopy (AttributeValue &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    *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;
} // AttributeSetOf::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.
AttributeSetOf &AttributeSetOf::InsertBeforeAndCopy (AttributeValue &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    *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;
} // AttributeSetOf::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.
AttributeSetOf  &AttributeSetOf::InsertAfterAndCopy (AttributeValue &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeValue;
    *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;
} // AttributeSetOf::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 AttributeSetOf::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 AttributeSetOf::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)
      {
        tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // AttributeSetOf::BEncContent


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

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        listElmt = Append();
        DEC_LOAD_ANYBUF(listElmt, b, listBytesDecoded, env);
    }

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


Attribute::Attribute()
{
}

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

Attribute::~Attribute()
{
}

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

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

#if SNACC_DEEP_COPY
Attribute &Attribute::operator = (const Attribute &that)
#else // SNACC_DEEP_COPY
Attribute &Attribute::operator = (const Attribute &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    type = that.type;
    values = that.values;
  }

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

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

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

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

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

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

  return totalLen;
} // Attribute::BEncContent


void Attribute::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);
    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-107);
  }

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

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

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

void Attribute::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 << "Attribute::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-110);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

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

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


AttributeTypeAndDistinguishedValue::AttributeTypeAndDistinguishedValue()
{
  primaryDistinguished = NULL;
  valuesWithContext = NULL;
}

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

AttributeTypeAndDistinguishedValue::~AttributeTypeAndDistinguishedValue()
{
  delete primaryDistinguished;
  delete valuesWithContext;
}

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

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

#if SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValue &AttributeTypeAndDistinguishedValue::operator = (const AttributeTypeAndDistinguishedValue &that)
#else // SNACC_DEEP_COPY
AttributeTypeAndDistinguishedValue &AttributeTypeAndDistinguishedValue::operator = (const AttributeTypeAndDistinguishedValue &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    type = that.type;
    value = that.value;
    if (that.primaryDistinguished)
    {
      if (!primaryDistinguished)
        primaryDistinguished = new AsnBool;
      *primaryDistinguished = *that.primaryDistinguished;
    }
    else
    {
      delete primaryDistinguished;
      primaryDistinguished = NULL;
    }
    if (that.valuesWithContext)
    {
      if (!valuesWithContext)
        valuesWithContext = new AttributeTypeAndDistinguishedValueSetOf;
      *valuesWithContext = *that.valuesWithContext;
    }
    else
    {
      delete valuesWithContext;
      valuesWithContext = NULL;
    }
  }

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

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

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

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

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

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

        ENC_LOAD_ANYBUF(&value, b, l);
    totalLen += l;

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

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

  return totalLen;
} // AttributeTypeAndDistinguishedValue::BEncContent


void AttributeTypeAndDistinguishedValue::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);
    type.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-111);
  }

  // ANY type
        DEC_LOAD_ANYBUF(&value, 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 (UNIV, PRIM, BOOLEAN_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    primaryDistinguished = new AsnBool;
    primaryDistinguished->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, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    valuesWithContext = new AttributeTypeAndDistinguishedValueSetOf;
    valuesWithContext->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(-112);
  }
  else
    return;
} // AttributeTypeAndDistinguishedValue::BDecContent

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

void AttributeTypeAndDistinguishedValue::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 << "AttributeTypeAndDistinguishedValue::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-113);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

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

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

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

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


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

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

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

void RelativeDistinguishedName::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 << "RelativeDistinguishedName::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-114);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &that)
#else // SNACC_DEEP_COPY
RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &)
#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 RelativeDistinguishedName &RelativeDistinguishedName::operator = (const RelativeDistinguishedName &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void RelativeDistinguishedName::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  RelativeDistinguishedName::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;
} // RelativeDistinguishedName::SetCurrElmt


unsigned long int  RelativeDistinguishedName::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;
} // RelativeDistinguishedName::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
AttributeTypeAndDistinguishedValue *RelativeDistinguishedName::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new AttributeTypeAndDistinguishedValue;
    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;
} // RelativeDistinguishedName::Append


// alloc new list elmt, put at begining of list
//  and return the component type
AttributeTypeAndDistinguishedValue  *RelativeDistinguishedName::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    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;
} // RelativeDistinguishedName::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.
AttributeTypeAndDistinguishedValue  *RelativeDistinguishedName::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    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;
} // RelativeDistinguishedName::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.
AttributeTypeAndDistinguishedValue *RelativeDistinguishedName::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    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;
} // RelativeDistinguishedName::InsertAfter


RelativeDistinguishedName  &RelativeDistinguishedName::AppendCopy (AttributeTypeAndDistinguishedValue &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    *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


RelativeDistinguishedName  &RelativeDistinguishedName::PrependCopy (AttributeTypeAndDistinguishedValue &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    *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;
} // RelativeDistinguishedName::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.
RelativeDistinguishedName &RelativeDistinguishedName::InsertBeforeAndCopy (AttributeTypeAndDistinguishedValue &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    *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;
} // RelativeDistinguishedName::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.
RelativeDistinguishedName  &RelativeDistinguishedName::InsertAfterAndCopy (AttributeTypeAndDistinguishedValue &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new AttributeTypeAndDistinguishedValue;
    *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;
} // RelativeDistinguishedName::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 RelativeDistinguishedName::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 RelativeDistinguishedName::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;
} // RelativeDistinguishedName::BEncContent


void  RelativeDistinguishedName::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    AttributeTypeAndDistinguishedValue *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(-115);
        }

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

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


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

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

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

void RDNSequence::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 << "RDNSequence::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-116);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
RDNSequence &RDNSequence::operator = (const RDNSequence &that)
#else // SNACC_DEEP_COPY
RDNSequence &RDNSequence::operator = (const RDNSequence &)
#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 RDNSequence &RDNSequence::operator = (const RDNSequence &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void RDNSequence::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  RDNSequence::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;
} // RDNSequence::SetCurrElmt


unsigned long int  RDNSequence::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;
} // RDNSequence::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
RelativeDistinguishedName *RDNSequence::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new RelativeDistinguishedName;
    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;
} // RDNSequence::Append


// alloc new list elmt, put at begining of list
//  and return the component type
RelativeDistinguishedName  *RDNSequence::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    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;
} // RDNSequence::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.
RelativeDistinguishedName  *RDNSequence::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    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;
} // RDNSequence::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.
RelativeDistinguishedName *RDNSequence::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    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;
} // RDNSequence::InsertAfter


RDNSequence  &RDNSequence::AppendCopy (RelativeDistinguishedName &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    *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


RDNSequence  &RDNSequence::PrependCopy (RelativeDistinguishedName &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    *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;
} // RDNSequence::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.
RDNSequence &RDNSequence::InsertBeforeAndCopy (RelativeDistinguishedName &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    *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;
} // RDNSequence::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.
RDNSequence  &RDNSequence::InsertAfterAndCopy (RelativeDistinguishedName &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RelativeDistinguishedName;
    *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;
} // RDNSequence::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 RDNSequence::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 RDNSequence::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;
} // RDNSequence::BEncContent


void  RDNSequence::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    RelativeDistinguishedName *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(-117);
        }

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

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


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

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

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

void Attributes::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 << "Attributes::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-118);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

#if SNACC_DEEP_COPY
Attributes &Attributes::operator = (const Attributes &that)
#else // SNACC_DEEP_COPY
Attributes &Attributes::operator = (const Attributes &)
#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 Attributes &Attributes::operator = (const Attributes &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void Attributes::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  Attributes::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;
} // Attributes::SetCurrElmt


unsigned long int  Attributes::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;
} // Attributes::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
Attribute *Attributes::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;
} // Attributes::Append


// alloc new list elmt, put at begining of list
//  and return the component type
Attribute  *Attributes::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;
} // Attributes::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  *Attributes::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;
} // Attributes::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 *Attributes::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;
} // Attributes::InsertAfter


Attributes  &Attributes::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


Attributes  &Attributes::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;
} // Attributes::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.
Attributes &Attributes::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;
} // Attributes::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.
Attributes  &Attributes::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;
} // Attributes::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 Attributes::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 Attributes::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;
} // Attributes::BEncContent


void  Attributes::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(-119);
        }

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

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


Name::Name()
{
  choiceId = rDNSequenceCid;
#if TCL
  rDNSequence = new RDNSequence;
#else
  rDNSequence = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

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

Name::~Name()
{
  switch (choiceId)
  {
    case rDNSequenceCid:
      delete rDNSequence;
      break;
  } // end of switch
} // end of destructor

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

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

#if SNACC_DEEP_COPY
Name &Name::operator = (const Name &that)
#else // SNACC_DEEP_COPY
Name &Name::operator = (const Name &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case rDNSequenceCid:
        delete rDNSequence;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case rDNSequenceCid:
        rDNSequence = new RDNSequence;
        *rDNSequence = *that.rDNSequence;
        break;
    }
  }

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

AsnLen
Name::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case rDNSequenceCid:
      BEncEocIfNec (b);
      l = rDNSequence->BEncContent (b);
    l += BEncConsLen (b, l);

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

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


void Name::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = rDNSequenceCid;
      rDNSequence = new RDNSequence;
        rDNSequence->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

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


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

void Name::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 Name::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case rDNSequenceCid:
      os << "rDNSequence ";
      if (rDNSequence)
        os << *rDNSequence;
      else
        os << "-- void3 --\n";
      break;

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

