/*
FILE:     _maxit.C
*/
/*
VERSION:  1.600
*/
/*
DATE:     2/3/2005
*/
/*
  Comments and Questions to: sw-help@rcsb.rutgers.edu
*/
/*
COPYRIGHT 1999-2005 Rutgers - The State University of New Jersey

This software is provided WITHOUT WARRANTY OF MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE OR ANY OTHER WARRANTY, EXPRESS OR
IMPLIED.  RUTGERS MAKE NO REPRESENTATION OR WARRANTY THAT THE
SOFTWARE WILL NOT INFRINGE ANY PATENT, COPYRIGHT OR OTHER
PROPRIETARY RIGHT.

The user of this software shall indemnify, hold harmless and defend
Rutgers, its governors, trustees, officers, employees, students,
agents and the authors against any and all claims, suits,
losses, liabilities, damages, costs, fees, and expenses including
reasonable attorneys' fees resulting from or arising out of the
use of this software.  This indemnification shall include, but is
not limited to, any and all claims alleging products liability.
*/
/*
               PDB SOFTWARE LICENSE AGREEMENT

BY CLICKING THE ACCEPTANCE BUTTON OR INSTALLING OR USING 
THIS "SOFTWARE, THE INDIVIDUAL OR ENTITY LICENSING THE  
SOFTWARE ("LICENSEE") IS CONSENTING TO BE BOUND BY AND IS 
BECOMING A PARTY TO THIS AGREEMENT.  IF LICENSEE DOES NOT 
AGREE TO ALL OF THE TERMS OF THIS AGREEMENT
THE LICENSEE MUST NOT INSTALL OR USE THE SOFTWARE.

1. LICENSE AGREEMENT

This is a license between you ("Licensee") and the Protein Data Bank (PDB) 
at Rutgers, The State University of New Jersey (hereafter referred to 
as "RUTGERS").   The software is owned by RUTGERS and protected by 
copyright laws, and some elements are protected by laws governing 
trademarks, trade dress and trade secrets, and may be protected by 
patent laws. 

2. LICENSE GRANT

RUTGERS grants you, and you hereby accept, non-exclusive, royalty-free 
perpetual license to install, use, modify, prepare derivative works, 
incorporate into other computer software, and distribute in binary 
and source code format, or any derivative work thereof, together with 
any associated media, printed materials, and on-line or electronic 
documentation (if any) provided by RUTGERS (collectively, the "SOFTWARE"), 
subject to the following terms and conditions: (i) any distribution 
of the SOFTWARE shall bind the receiver to the terms and conditions 
of this Agreement; (ii) any distribution of the SOFTWARE in modified 
form shall clearly state that the SOFTWARE has been modified from 
the version originally obtained from RUTGERS.  

2. COPYRIGHT; RETENTION OF RIGHTS.  

The above license grant is conditioned on the following: (i) you must 
reproduce all copyright notices and other proprietary notices on any 
copies of the SOFTWARE and you must not remove such notices; (ii) in 
the event you compile the SOFTWARE, you will include the copyright 
notice with the binary in such a manner as to allow it to be easily 
viewable; (iii) if you incorporate the SOFTWARE into other code, you 
must provide notice that the code contains the SOFTWARE and include 
a copy of the copyright notices and other proprietary notices.  All 
copies of the SOFTWARE shall be subject to the terms of this Agreement.  

3. NO MAINTENANCE OR SUPPORT; TREATMENT OF ENHANCEMENTS 

RUTGERS is under no obligation whatsoever to: (i) provide maintenance 
or support for the SOFTWARE; or (ii) to notify you of bug fixes, patches, 
or upgrades to the features, functionality or performance of the 
SOFTWARE ("Enhancements") (if any), whether developed by RUTGERS 
or third parties.  If, in its sole discretion, RUTGERS makes an 
Enhancement available to you and RUTGERS does not separately enter 
into a written license agreement with you relating to such bug fix, 
patch or upgrade, then it shall be deemed incorporated into the SOFTWARE 
and subject to this Agreement. You are under no obligation whatsoever 
to provide any Enhancements to RUTGERS or the public that you may 
develop over time; however, if you choose to provide your Enhancements 
to RUTGERS, or if you choose to otherwise publish or distribute your 
Enhancements, in source code form without contemporaneously requiring 
end users or RUTGERS to enter into a separate written license agreement 
for such Enhancements, then you hereby grant RUTGERS a non-exclusive,
royalty-free perpetual license to install, use, modify, prepare
derivative works, incorporate into the SOFTWARE or other computer
software, distribute, and sublicense your Enhancements or derivative
works thereof, in binary and source code form.

4. FEES.  There is no license fee for the SOFTWARE.  If Licensee
wishes to receive the SOFTWARE on media, there may be a small charge
for the media and for shipping and handling.  Licensee is
responsible for any and all taxes.

5. TERMINATION.  Without prejudice to any other rights, Licensor
may terminate this Agreement if Licensee breaches any of its terms
and conditions.  Upon termination, Licensee shall destroy all
copies of the SOFTWARE.

6. PROPRIETARY RIGHTS.  Title, ownership rights, and intellectual
property rights in the Product shall remain with RUTGERS.  Licensee 
acknowledges such ownership and intellectual property rights and will 
not take any action to jeopardize, limit or interfere in any manner 
with RUTGERS' ownership of or rights with respect to the SOFTWARE.  
The SOFTWARE is protected by copyright and other intellectual 
property laws and by international treaties.  Title and related 
rights in the content accessed through the SOFTWARE is the property 
of the applicable content owner and is protected by applicable law.  
The license granted under this Agreement gives Licensee no rights to such
content.

7. DISCLAIMER OF WARRANTY.  THE SOFTWARE IS PROVIDED FREE OF 
CHARGE, AND, THEREFORE, ON AN "AS IS" BASIS, WITHOUT WARRANTY OF 
ANY KIND, INCLUDING WITHOUT LIMITATION THE WARRANTIES THAT IT 
IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE 
OR NON-INFRINGING.  THE ENTIRE RISK AS TO THE QUALITY AND 
PERFORMANCE OF THE SOFTWARE IS BORNE BY LICENSEE.  SHOULD THE 
SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, THE LICENSEE AND NOT 
LICENSOR ASSUMES THE ENTIRE COST OF ANY SERVICE AND REPAIR.  
THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF 
THIS AGREEMENT.  NO USE OF THE PRODUCT IS AUTHORIZED HEREUNDER 
EXCEPT UNDER THIS DISCLAIMER.

8. LIMITATION OF LIABILITY.  TO THE MAXIMUM EXTENT PERMITTED BY
APPLICABLE LAW,  IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY 
INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 
OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, INCLUDING, 
WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL 
OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF ADVISED OF THE
POSSIBILITY THEREOF. 
*/
#include <stdio.h>
#include <string.h>

#include "_maxit.h"
#include "erf_category.h"
#include "ndb_misclib.h"
#include "erf_util.h"
#include "util.h"
#include "_fileobj_ioutil.h"

#define NUM_TOKENS  84

static char merge_tokens[NUM_TOKENS][7] = {
       "BVALUE", "COFOFC", "CRMET1", "CRMETH", "DIFPTL", "DTMEA1", "DTMEAS", "DTMETH", "DTTEMP", "REFESU",
       "EXPDTA", "FREERF", "NCSMOD", "NMRECD", "NMREXP", "NMRPST", "NMRSDT", "NMRSFT", "NMRSMB", "NMRSMP",
       "NMRSPM", "PERCOM", "PHVAL",  "R4SCUT", "RADIAT", "REFERR", "REFINE", "REFLEC", "REFMET", "REFREM",
       "RESTOT", "RFACTR", "RMSCON", "RMSDIN", "RMSDIS", "RMSGEN", "RMSISN", "RMSISO", "RMSNBO", "RMSPLA",
       "RMSRF1", "RMSRF2", "RMSRF3", "RMSRF4", "RMSRF5", "RMSRF6", "RMSRF7", "RMSRF8", "RMSTN1", "RMSTN2",
       "RMSVOL", "RNOCUT", "SHELC",  "SHELL",  "SHELXL", "SOLMOD", "SFTWAR", "WAVLEN", "XFILE1", "XFILE2",
       "XFILE3", "XFILES", "SOLEXP", "SOLMDL", "CMRFMT", "CEMFIT", "CMRNST", "EMSAMP", "EMDATA", "ASSEMB",
       "VIRPAR", "TLSRNG", "TLSGRO", "TTENSR", "LTENSR", "STENSR", "RFTPOS", "RFMPOS", "RFLPOS", "RFTTHR",
       "RFMTHR", "RFLTHR", "CCPNCS", "TMLPTL"
};



_MAXIT::_MAXIT(const int mxtokens, const int mxjrnltokens): _VALIDATION(mxtokens, mxjrnltokens)
{
       _alloc_sheet = 0; _n_sheet = 0; _sheet = NULL;
       _alloc_ssbond = 0; _n_ssbond = 0; _ssbond = NULL;
       _alloc_hydbnd = 0; _n_hydbnd = 0; _hydbnd = NULL;
       _alloc_sltbrg = 0; _n_sltbrg = 0; _sltbrg = NULL;
       _alloc_site = 0; _n_site = 0; _site = NULL;
       _alloc_het = 0; _n_het = 0; _het = NULL;
       _alloc_modifb = 0; _n_modifb = 0; _modifb = NULL;
       _alloc_modifp = 0; _n_modifp = 0; _modifp = NULL;
       _alloc_modifs = 0; _n_modifs = 0; _modifs = NULL;
       _alloc_modres = 0; _n_modres = 0; _modres = NULL;
       _n_entity = 0;
       _entity = NULL;
       _exist_helix = 0;
       _exist_sheet = 0;
       _exist_ssbond = 0;
       _create_final_file = 0;
       _n_biol_unit_info = 0; _biol_unit_info = NULL;
}

_MAXIT::~_MAXIT()
{
       int i, j;
       Clear_Structural_Feature();
       if (_entity) {
            for (i = 0; i < _n_entity; i++) {
                 if (_entity[i].Type) delete [] _entity[i].Type;
                 if (_entity[i].Source) delete [] _entity[i].Source;
                 if (_entity[i].Description) delete [] _entity[i].Description;
            }
            delete [] _entity;
       }
       if (_biol_unit_info) {
            for (i = 0; i < _n_biol_unit_info; i++) {
                 if (_biol_unit_info[i]) {
                      if (_biol_unit_info[i]->stbiol) {
                           for (j = 0; j < _biol_unit_info[i]->n_stbiol; j++) {
                                if (_biol_unit_info[i]->stbiol[j]) {
                                     delete _biol_unit_info[i]->stbiol[j];
                                }
                           }
                           delete [] _biol_unit_info[i]->stbiol;
                      }
                      delete _biol_unit_info[i];
                 }
            }
            delete [] _biol_unit_info;
       }
}

void _MAXIT::Clear_Structural_Feature()
{
       int i;
       if (_sheet) {
            for (i = 0; i < _n_sheet; i++)
                 if (_sheet[i]) delete _sheet[i];
            delete [] _sheet;
       }
       if (_ssbond) {
            for (i = 0; i < _n_ssbond; i++)
                 if (_ssbond[i]) delete _ssbond[i];
            delete [] _ssbond;
       }
       if (_hydbnd) {
            for (i = 0; i < _n_hydbnd; i++)
                 if (_hydbnd[i]) delete _hydbnd[i];
            delete [] _hydbnd;
       }
       if (_sltbrg) {
            for (i = 0; i < _n_sltbrg; i++) {
                 if (_sltbrg[i]) {
                      if (_sltbrg[i]->details) delete _sltbrg[i]->details;
                      delete _sltbrg[i];
                 }
            }
            delete [] _sltbrg;
       }
       if (_site) {
            for (i = 0; i < _n_site; i++) {
                 if (_site[i]) {
                      if (_site[i]->initIndex)
                           delete [] _site[i]->initIndex;
                      if (_site[i]->initRes)
                           delete [] _site[i]->initRes;
                      delete _site[i];
                 }
            }
            delete [] _site;
       }
       if (_het) {
            for (i = 0; i < _n_het; i++)
                 if (_het[i]) delete _het[i];
            delete [] _het;
       }
       if (_modifb) {
            for (i = 0; i < _n_modifb; i++)
                 if (_modifb[i]) delete _modifb[i];
            delete [] _modifb;
       }
       if (_modifp) {
            for (i = 0; i < _n_modifp; i++)
                 if (_modifp[i]) delete _modifp[i];
            delete [] _modifp;
       }
       if (_modifs) {
            for (i = 0; i < _n_modifs; i++)
                 if (_modifs[i]) delete _modifs[i];
            delete [] _modifs;
       }
       if (_modres) {
            for (i = 0; i < _n_modres; i++) {
                 if (_modres[i]) {
                      if (_modres[i]->details) delete _modres[i]->details;
                      delete _modres[i];
                 }
            }
            delete [] _modres;
       }
}

void _MAXIT::Insert_a_Sheet(const char *id, const int numStrands, const int initIndex,
               const int initRes, const int endIndex, const int endRes, const int sense,
               const char *curAtom, const int curIndex, const int curRes,
               const char *prevAtom, const int prevIndex, const int prevRes)
{
       int i;
       _SHEET** tmp = NULL;
       if (_n_sheet >= _alloc_sheet) {
            _alloc_sheet += 20;
            tmp = _sheet;
            _sheet = new _SHEET*[_alloc_sheet];
            for (i = 0; i < _n_sheet; i++) _sheet[i] = tmp[i];
            for (i = _n_sheet; i < _alloc_sheet; i++) _sheet[i] = NULL;
            delete [] tmp;
       }
       _sheet[_n_sheet] = new _SHEET;
       strcpy(_sheet[_n_sheet]->sheetID, id);
       _sheet[_n_sheet]->numStrands = numStrands;
       _sheet[_n_sheet]->initIndex = initIndex;
       _sheet[_n_sheet]->initRes = initRes;
       _sheet[_n_sheet]->endIndex = endIndex;
       _sheet[_n_sheet]->endRes = endRes;
       _sheet[_n_sheet]->sense = sense;
       strcpy(_sheet[_n_sheet]->curAtom, curAtom);
       _sheet[_n_sheet]->curIndex = curIndex;
       _sheet[_n_sheet]->curRes = curRes;
       strcpy(_sheet[_n_sheet]->prevAtom, prevAtom);
       _sheet[_n_sheet]->prevIndex = prevIndex;
       _sheet[_n_sheet]->prevRes = prevRes;
       _n_sheet++;
}

void _MAXIT::Insert_a_SSbond(const int FstIndex, const int FstRes, const int SndIndex,
                  const int SndRes, const char *SymOP_1, const char *SymOP_2)
{
       int i;
       _SSBOND** tmp = NULL;
       for (i = 0; i < _n_ssbond; i++) {
            if (_ssbond[i]->FstIndex == FstIndex && _ssbond[i]->FstRes == FstRes &&
                _ssbond[i]->SndIndex == SndIndex && _ssbond[i]->SndRes == SndRes &&
                !strcmp(_ssbond[i]->SymOP_1, SymOP_1) &&
                !strcmp(_ssbond[i]->SymOP_2, SymOP_2)) break;
       }
       if (i < _n_ssbond) return;

       if (_n_ssbond >= _alloc_ssbond) {
            _alloc_ssbond += 5;
            tmp = _ssbond;
            _ssbond = new _SSBOND*[_alloc_ssbond];
            for (i = 0; i < _n_ssbond; i++) _ssbond[i] = tmp[i];
            for (i = _n_ssbond; i < _alloc_ssbond; i++) _ssbond[i] = NULL;
            delete [] tmp;
       }
       _ssbond[_n_ssbond] = new _SSBOND;
       _ssbond[_n_ssbond]->FstIndex = FstIndex;
       _ssbond[_n_ssbond]->FstRes = FstRes;
       _ssbond[_n_ssbond]->SndIndex = SndIndex;
       _ssbond[_n_ssbond]->SndRes = SndRes;
       strcpy(_ssbond[_n_ssbond]->SymOP_1, SymOP_1);
       strcpy(_ssbond[_n_ssbond]->SymOP_2, SymOP_2);
       _n_ssbond++;
}

void _MAXIT::Insert_a_Hydbnd(const char *FstAtom, const char *altLoc1, const int FstIndex,
           const int FstRes, const char *H_Atom, const char *altLocH, const int H_Index,
           const int H_Res, const char *SndAtom, const char *altLoc2, const int SndIndex,
           const int SndRes, const char *SymOP_1, const char *SymOP_2)
{
       int i;
       _HYDBND** tmp = NULL;
       for (i = 0; i < _n_hydbnd; i++) {
            if (!strcmp(_hydbnd[i]->FstAtom, FstAtom) &&
                !strcmp(_hydbnd[i]->altLoc1, altLoc1) &&
                _hydbnd[i]->FstIndex == FstIndex && _hydbnd[i]->FstRes == FstRes &&
                !strcmp(_hydbnd[i]->H_Atom, H_Atom) &&
                !strcmp(_hydbnd[i]->altLocH, altLocH) &&
                _hydbnd[i]->H_Index == H_Index && _hydbnd[i]->H_Res == H_Res &&
                !strcmp(_hydbnd[i]->SndAtom, SndAtom) &&
                !strcmp(_hydbnd[i]->altLoc2, altLoc2) &&
                _hydbnd[i]->SndIndex == SndIndex && _hydbnd[i]->SndRes == SndRes &&
                !strcmp(_hydbnd[i]->SymOP_1, SymOP_1) &&
                !strcmp(_hydbnd[i]->SymOP_2, SymOP_2)) break;
       }
       if (i < _n_hydbnd) return;

       if (_n_hydbnd >= _alloc_hydbnd) {
            _alloc_hydbnd += 5;
            tmp = _hydbnd;
            _hydbnd = new _HYDBND*[_alloc_hydbnd];
            for (i = 0; i < _n_hydbnd; i++) _hydbnd[i] = tmp[i];
            for (i = _n_hydbnd; i < _alloc_hydbnd; i++) _hydbnd[i] = NULL;
            delete [] tmp;
       }
       _hydbnd[_n_hydbnd] = new _HYDBND;
       strcpy(_hydbnd[_n_hydbnd]->FstAtom, FstAtom);
       strcpy(_hydbnd[_n_hydbnd]->altLoc1, altLoc1);
       _hydbnd[_n_hydbnd]->FstIndex = FstIndex;
       _hydbnd[_n_hydbnd]->FstRes = FstRes;
       strcpy(_hydbnd[_n_hydbnd]->H_Atom, H_Atom);
       strcpy(_hydbnd[_n_hydbnd]->altLocH, altLocH);
       _hydbnd[_n_hydbnd]->H_Index = H_Index;
       _hydbnd[_n_hydbnd]->H_Res = H_Res;
       strcpy(_hydbnd[_n_hydbnd]->SndAtom, SndAtom);
       strcpy(_hydbnd[_n_hydbnd]->altLoc2, altLoc2);
       _hydbnd[_n_hydbnd]->SndIndex = SndIndex;
       _hydbnd[_n_hydbnd]->SndRes = SndRes;
       strcpy(_hydbnd[_n_hydbnd]->SymOP_1, SymOP_1);
       strcpy(_hydbnd[_n_hydbnd]->SymOP_2, SymOP_2);
       _n_hydbnd++;
}

void _MAXIT::Insert_a_Sltbrg(const char *FstAtom, const char *altLoc1, const int FstIndex,
           const int FstRes, const char *SndAtom, const char *altLoc2, const int SndIndex,
           const int SndRes, const char *SymOP_1, const char *SymOP_2)
{
       int i;
       _SLTBRG** tmp = NULL;
       for (i = 0; i < _n_sltbrg; i++) {
            if (!strcmp(_sltbrg[i]->FstAtom, FstAtom) &&
                !strcmp(_sltbrg[i]->altLoc1, altLoc1) &&
                _sltbrg[i]->FstIndex == FstIndex && _sltbrg[i]->FstRes == FstRes &&
                !strcmp(_sltbrg[i]->SndAtom, SndAtom) &&
                !strcmp(_sltbrg[i]->altLoc2, altLoc2) &&
                _sltbrg[i]->SndIndex == SndIndex && _sltbrg[i]->SndRes == SndRes &&
                !strcmp(_sltbrg[i]->SymOP_1, SymOP_1) &&
                !strcmp(_sltbrg[i]->SymOP_2, SymOP_2)) break;
       }
       if (i < _n_sltbrg) return;

       if (_n_sltbrg >= _alloc_sltbrg) {
            _alloc_sltbrg += 5;
            tmp = _sltbrg;
            _sltbrg = new _SLTBRG*[_alloc_sltbrg];
            for (i = 0; i < _n_sltbrg; i++) _sltbrg[i] = tmp[i];
            for (i = _n_sltbrg; i < _alloc_sltbrg; i++) _sltbrg[i] = NULL;
            delete [] tmp;
       }
       _sltbrg[_n_sltbrg] = new _SLTBRG;
       strcpy(_sltbrg[_n_sltbrg]->FstAtom, FstAtom);
       strcpy(_sltbrg[_n_sltbrg]->altLoc1, altLoc1);
       _sltbrg[_n_sltbrg]->FstIndex = FstIndex;
       _sltbrg[_n_sltbrg]->FstRes = FstRes;
       strcpy(_sltbrg[_n_sltbrg]->SndAtom, SndAtom);
       strcpy(_sltbrg[_n_sltbrg]->altLoc2, altLoc2);
       _sltbrg[_n_sltbrg]->SndIndex = SndIndex;
       _sltbrg[_n_sltbrg]->SndRes = SndRes;
       strcpy(_sltbrg[_n_sltbrg]->SymOP_1, SymOP_1);
       strcpy(_sltbrg[_n_sltbrg]->SymOP_2, SymOP_2);
       _sltbrg[_n_sltbrg]->details = NULL;
       _n_sltbrg++;
}

void _MAXIT::Insert_a_Site(const char *SiteID, const int initIndex, const int initRes)
{
       int i, j;
       _SITE** tmp = NULL;
       for (i = 0; i < _n_site; i++) {
            if (!strcmp(SiteID, _site[i]->SiteID)) break;
       }
       if (i == _n_site) {
            if (_n_site >= _alloc_site) {
                 _alloc_site += 10;
                 tmp = _site;
                 _site = new _SITE*[_alloc_site];
                 for (j = 0; j < _n_site; j++) _site[j] = tmp[j];
                 for (j = _n_site; j < _alloc_site; j++) _site[j] = NULL;
                 delete [] tmp;
            }
            _site[_n_site] = new _SITE;
            _n_site++;
            strcpy(_site[i]->SiteID, SiteID);
            _site[i]->numRes = 0;
            _site[i]->alloc_numRes = 5;
            _site[i]->initIndex = new int[5];
            _site[i]->initRes = new int[5];
       }
       for (j = 0; j < _site[i]->numRes; j++) {
            if (_site[i]->initIndex[j] == initIndex &&
                _site[i]->initRes[j] == initRes) break;
       }
       if (j == _site[i]->numRes) {
            if (_site[i]->numRes >= _site[i]->alloc_numRes) {
                 _site[i]->alloc_numRes += 5;
                 int *tmp = _site[i]->initIndex;
                 _site[i]->initIndex = new int[_site[i]->alloc_numRes];
                 for (j = 0; j < _site[i]->numRes; j++)
                      _site[i]->initIndex[j] = tmp[j];
                 delete [] tmp;
                 tmp = _site[i]->initRes;
                 _site[i]->initRes = new int[_site[i]->alloc_numRes];
                 for (j = 0; j < _site[i]->numRes; j++)
                      _site[i]->initRes[j] = tmp[j];
                 delete [] tmp;
            }
            _site[i]->initIndex[_site[i]->numRes] = initIndex;
            _site[i]->initRes[_site[i]->numRes] = initRes;
            _site[i]->numRes++;
       }
}

void _MAXIT::Insert_a_Het(const int initIndex, const int initRes, const int numAtoms)
{
       int i;
       _HET** tmp = NULL;
       for (i = 0; i < _n_het; i++) {
            if (_het[i]->initIndex == initIndex && _het[i]->initRes == initRes) break;
       }
       if (i < _n_het) return;

       if (_n_het >= _alloc_het) {
            _alloc_het += 5;
            tmp = _het;
            _het = new _HET*[_alloc_het];
            for (i = 0; i < _n_het; i++) _het[i] = tmp[i];
            for (i = _n_het; i < _alloc_het; i++) _het[i] = NULL;
            delete [] tmp;
       }
       _het[_n_het] = new _HET;
       _het[_n_het]->initIndex = initIndex;
       _het[_n_het]->initRes = initRes;
       _het[_n_het]->numAtoms = numAtoms;
       _n_het++;
}

void _MAXIT::Insert_a_Modifb(const char *Name, const char *FstAtom, const int FstIndex,
           const int FstRes, const char *SndAtom, const int SndIndex, const int SndRes,
           const char *Replaced_Atom)
{
       int i;
       _MODIFB** tmp = NULL;
       for (i = 0; i < _n_modifb; i++) {
            if (!strcmp(_modifb[i]->FstAtom, FstAtom) &&
                _modifb[i]->FstIndex == FstIndex && _modifb[i]->FstRes == FstRes &&
                !strcmp(_modifb[i]->SndAtom, SndAtom) &&
                _modifb[i]->SndIndex == SndIndex && _modifb[i]->SndRes == SndRes &&
                !strcmp(_modifb[i]->Replaced_Atom, Replaced_Atom)) break;
       }
       if (i < _n_modifb) return;

       if (_n_modifb >= _alloc_modifb) {
            _alloc_modifb += 5;
            tmp = _modifb;
            _modifb = new _MODIFB*[_alloc_modifb];
            for (i = 0; i < _n_modifb; i++) _modifb[i] = tmp[i];
            for (i = _n_modifb; i < _alloc_modifb; i++) _modifb[i] = NULL;
            delete [] tmp;
       }
       _modifb[_n_modifb] = new _MODIFB;
       strcpy(_modifb[_n_modifb]->Name, Name);
       strcpy(_modifb[_n_modifb]->FstAtom, FstAtom);
       _modifb[_n_modifb]->FstIndex = FstIndex;
       _modifb[_n_modifb]->FstRes = FstRes;
       strcpy(_modifb[_n_modifb]->SndAtom, SndAtom);
       _modifb[_n_modifb]->SndIndex = SndIndex;
       _modifb[_n_modifb]->SndRes = SndRes;
       strcpy(_modifb[_n_modifb]->Replaced_Atom, Replaced_Atom);
       _n_modifb++;
}

void _MAXIT::Insert_a_Modifp(const char *Name, const char *FstAtom, const int FstIndex,
           const int FstRes, const char *SndAtom, const int SndIndex, const int SndRes,
           const char *Replaced_Atom)
{
       int i;
       _MODIFP** tmp = NULL;
       for (i = 0; i < _n_modifp; i++) {
            if (!strcmp(_modifp[i]->FstAtom, FstAtom) &&
                _modifp[i]->FstIndex == FstIndex && _modifp[i]->FstRes == FstRes &&
                !strcmp(_modifp[i]->SndAtom, SndAtom) &&
                _modifp[i]->SndIndex == SndIndex && _modifp[i]->SndRes == SndRes &&
                !strcmp(_modifp[i]->Replaced_Atom, Replaced_Atom)) break;
       }
       if (i < _n_modifp) return;

       if (_n_modifp >= _alloc_modifp) {
            _alloc_modifp += 5;
            tmp = _modifp;
            _modifp = new _MODIFP*[_alloc_modifp];
            for (i = 0; i < _n_modifp; i++) _modifp[i] = tmp[i];
            for (i = _n_modifp; i < _alloc_modifp; i++) _modifp[i] = NULL;
            delete [] tmp;
       }
       _modifp[_n_modifp] = new _MODIFP;
       strcpy(_modifp[_n_modifp]->Name, Name);
       strcpy(_modifp[_n_modifp]->FstAtom, FstAtom);
       _modifp[_n_modifp]->FstIndex = FstIndex;
       _modifp[_n_modifp]->FstRes = FstRes;
       strcpy(_modifp[_n_modifp]->SndAtom, SndAtom);
       _modifp[_n_modifp]->SndIndex = SndIndex;
       _modifp[_n_modifp]->SndRes = SndRes;
       strcpy(_modifp[_n_modifp]->Replaced_Atom, Replaced_Atom);
       _n_modifp++;
}

void _MAXIT::Insert_a_Modifs(const char *Name, const char *FstAtom, const int FstIndex,
           const int FstRes, const char *SndAtom, const int SndIndex, const int SndRes,
           const char *Replaced_Atom, const char *Sugar_Name)
{
       int i;
       _MODIFS** tmp = NULL;
       for (i = 0; i < _n_modifs; i++) {
            if (!strcmp(_modifs[i]->FstAtom, FstAtom) &&
                _modifs[i]->FstIndex == FstIndex && _modifs[i]->FstRes == FstRes &&
                !strcmp(_modifs[i]->SndAtom, SndAtom) &&
                _modifs[i]->SndIndex == SndIndex && _modifs[i]->SndRes == SndRes &&
                !strcmp(_modifs[i]->Replaced_Atom, Replaced_Atom) &&
                !strcmp(_modifs[i]->Sugar_Name, Sugar_Name)) break;
       }
       if (i < _n_modifs) return;

       if (_n_modifs >= _alloc_modifs) {
            _alloc_modifs += 5;
            tmp = _modifs;
            _modifs = new _MODIFS*[_alloc_modifs];
            for (i = 0; i < _n_modifs; i++) _modifs[i] = tmp[i];
            for (i = _n_modifs; i < _alloc_modifs; i++) _modifs[i] = NULL;
            delete [] tmp;
       }
       _modifs[_n_modifs] = new _MODIFS;
       strcpy(_modifs[_n_modifs]->Name, Name);
       strcpy(_modifs[_n_modifs]->FstAtom, FstAtom);
       _modifs[_n_modifs]->FstIndex = FstIndex;
       _modifs[_n_modifs]->FstRes = FstRes;
       strcpy(_modifs[_n_modifs]->SndAtom, SndAtom);
       _modifs[_n_modifs]->SndIndex = SndIndex;
       _modifs[_n_modifs]->SndRes = SndRes;
       strcpy(_modifs[_n_modifs]->Replaced_Atom, Replaced_Atom);
       strcpy(_modifs[_n_modifs]->Sugar_Name, Sugar_Name);
       _n_modifs++;
}

void _MAXIT::Insert_a_Modres(const char *PDB_ID, const int FstIndex, const int FstRes,
            const char *Standard_Name, const char *details)
{
       int i, len;
       _MODRES** tmp = NULL;
       for (i = 0; i < _n_modres; i++) {
            if (!strcmp(_modres[i]->PDB_ID, PDB_ID) && _modres[i]->FstIndex == FstIndex &&
                 _modres[i]->FstRes == FstRes) {
                 if (!Standard_Name) break;
                 else if (!strcmp(_modres[i]->Standard_Name, Standard_Name)) break;
                 else if (!strcmp(_modres[i]->Standard_Name, "")) break;
            }
       }
       if (i < _n_modres) {
            if (!strcmp(_modres[i]->Standard_Name, "") && Standard_Name &&
                 strcmp(Standard_Name, ""))
                 strcpy(_modres[i]->Standard_Name, Standard_Name);
            return;
       }

       if (_n_modres >= _alloc_modres) {
            _alloc_modres += 5;
            tmp = _modres;
            _modres = new _MODRES*[_alloc_modres];
            for (i = 0; i < _n_modres; i++) _modres[i] = tmp[i];
            for (i = _n_modres; i < _alloc_modres; i++) _modres[i] = NULL;
            delete [] tmp;
       }
       _modres[_n_modres] = new _MODRES;
       strcpy(_modres[_n_modres]->PDB_ID, PDB_ID);
       _modres[_n_modres]->FstIndex = FstIndex;
       _modres[_n_modres]->FstRes = FstRes;
       if (Standard_Name && strcmp(Standard_Name, ""))
            strcpy(_modres[_n_modres]->Standard_Name, Standard_Name);
       else strcpy(_modres[_n_modres]->Standard_Name, "");
       len = strlen(details) + 1;
       _modres[_n_modres]->details = new char[len];
       strcpy(_modres[_n_modres]->details, details);
       _n_modres++;
}

void _MAXIT::input_structural_features(const int format)
{
       if (_num_mol == 0 || _molecules == NULL) return;

       _MOLECULE *mol = _molecules[0];

       int i = 0, initIndex = -1, initRes = -1, endIndex = -1, endRes = -1;
       int curIndex = -1, curRes = -1, prevIndex = -1, prevRes = -1;
       int FstIndex = -1, FstRes = -1, SndIndex = -1, SndRes = -1;
       int H_Index = -1, H_Res = -1, snd_resnum = 0;
       char snd_chainid[5], symmetry[10];
       _CHAIN *chain = NULL;
       _FIELD *init = NULL, *end = NULL;
       One_Card_Info_Format *pCard = _CardInfo[HELIX_TOKEN-1].Head();
       while (pCard) {
            chain = mol->GetFirstChain();
            while (chain) {
                 if ((!strcmp(chain->PDB_ChainID(), pCard->Field(4)) &&
                      format == NDB_FILE_FORMAT_PDB ||
                     !strcmp(chain->ChainID(), pCard->Field(4)) &&
                      format == NDB_FILE_FORMAT_NDB)) break;
                 chain = mol->GetNextChain();
            }
            for (i = 0; i < mol->Num_Chain(); i++) {
            }
            if (chain) {
                 init = chain->find_Residue(format, pCard->Field(3),
                                 atoi(pCard->Field(5)), pCard->Field(6));
                 end = chain->find_Residue(format, pCard->Field(7),
                                 atoi(pCard->Field(9)), pCard->Field(10));
                 if (init && end) {
                      chain->Insert_a_Helix(pCard->Field(2), init->ResIndex,
                            end->ResIndex, atoi(pCard->Field(11)), pCard->Field(12));
                      _exist_helix = 1;
                 }
            }
            pCard = pCard->Next();
       }
       _CardInfo[HELIX_TOKEN-1].clear_Cards();

       pCard = _CardInfo[TURN_TOKEN-1].Head();
       while (pCard) {
            chain = mol->GetFirstChain();
            while (chain) {
                 if ((!strcmp(chain->PDB_ChainID(), pCard->Field(4)) &&
                      format == NDB_FILE_FORMAT_PDB ||
                     !strcmp(chain->ChainID(), pCard->Field(4)) &&
                      format == NDB_FILE_FORMAT_NDB) &&
                       chain->chain_type() == ATOMP_TOKEN) break;
                 chain = mol->GetNextChain();
            }
            if (chain) {
                 init = chain->find_Residue(format, pCard->Field(3),
                                  atoi(pCard->Field(5)), pCard->Field(6));
                 end  = chain->find_Residue(format, pCard->Field(7),
                                  atoi(pCard->Field(9)), pCard->Field(10));
                 if (init && end) {
                      chain->Insert_a_Turn(pCard->Field(2), init->ResIndex,
                            end->ResIndex, pCard->Field(11));
                 }
            }
            pCard = pCard->Next();
       }
       _CardInfo[TURN_TOKEN-1].clear_Cards();

       pCard = _CardInfo[SHEET_TOKEN-1].Head();
       while (pCard) {
            mol->find_residue(format, pCard->Field(15), pCard->Field(14),
                  atoi(pCard->Field(16)), pCard->Field(17), curIndex, curRes);
            mol->find_residue(format, pCard->Field(20), pCard->Field(19),
                  atoi(pCard->Field(21)), pCard->Field(22), prevIndex, prevRes);
            if (mol->find_residue(format, pCard->Field(5), pCard->Field(4),
                  atoi(pCard->Field(6)), pCard->Field(7), initIndex, initRes) &&
                mol->find_residue(format, pCard->Field(9), pCard->Field(8),
                  atoi(pCard->Field(10)), pCard->Field(11), endIndex, endRes)) {
                 Insert_a_Sheet(pCard->Field(2), atoi(pCard->Field(3)), initIndex,
                      initRes, endIndex, endRes, atoi(pCard->Field(12)),
                      pCard->Field(13), curIndex, curRes, pCard->Field(18),
                      prevIndex, prevRes);
                 _exist_sheet = 1;
            }
            pCard = pCard->Next();
       }
       _CardInfo[SHEET_TOKEN-1].clear_Cards();

       pCard = _CardInfo[SSBOND_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_residue(format, pCard->Field(3), pCard->Field(2),
                  atoi(pCard->Field(4)), pCard->Field(5), FstIndex, FstRes) &&
                mol->find_residue(format, pCard->Field(7), pCard->Field(6),
                  atoi(pCard->Field(8)), pCard->Field(9), SndIndex, SndRes)) {
                 Insert_a_SSbond(FstIndex, FstRes, SndIndex, SndRes,
                        pCard->Field(10), pCard->Field(11));
                 _exist_ssbond = 1;
            }
            pCard = pCard->Next();
       }
       _CardInfo[SSBOND_TOKEN-1].clear_Cards();
       Input_Link();

       pCard = _CardInfo[HYDBND_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_residue(format, pCard->Field(4), pCard->Field(3),
                   atoi(pCard->Field(5)), pCard->Field(6), FstIndex, FstRes) &&
                mol->find_residue(format, pCard->Field(15), pCard->Field(14),
                   atoi(pCard->Field(16)), pCard->Field(17), SndIndex, SndRes)) {
                 if (strcmp(pCard->Field(7), "")) {
                      if (!strcmp(pCard->Field(4), pCard->Field(9)) &&
                          !strcmp(pCard->Field(5), pCard->Field(10)) &&
                          !strcmp(pCard->Field(6), pCard->Field(11))) {
                           H_Index = FstIndex; H_Res = FstRes;
                      } else if (!strcmp(pCard->Field(4), pCard->Field(15)) &&
                          !strcmp(pCard->Field(5), pCard->Field(16)) &&
                          !strcmp(pCard->Field(6), pCard->Field(17))) {
                           H_Index = SndIndex; H_Res = SndRes;
                      }       
                 }
                 Insert_a_Hydbnd(pCard->Field(1), pCard->Field(2), FstIndex, FstRes,
                     pCard->Field(7), pCard->Field(8), H_Index, H_Res, pCard->Field(12),
                     pCard->Field(13), SndIndex, SndRes, pCard->Field(18), pCard->Field(19));
            }
            pCard = pCard->Next();
       }
       _CardInfo[HYDBND_TOKEN-1].clear_Cards();

       pCard = _CardInfo[SLTBRG_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_residue(format, pCard->Field(4), pCard->Field(3),
                   atoi(pCard->Field(5)), pCard->Field(6), FstIndex, FstRes) &&
                mol->find_residue(format, pCard->Field(10), pCard->Field(9),
                   atoi(pCard->Field(11)), pCard->Field(12), SndIndex, SndRes)) { 
                 Insert_a_Sltbrg(pCard->Field(1), pCard->Field(2), FstIndex, FstRes,
                        pCard->Field(7), pCard->Field(8), SndIndex, SndRes,
                        pCard->Field(13), pCard->Field(14));
            }
            pCard = pCard->Next();
       }
       _CardInfo[SLTBRG_TOKEN-1].clear_Cards();

       pCard = _CardInfo[SITE_TOKEN-1].Head();
       while (pCard) {
            if (strcmp(pCard->Field(4), "") && strcmp(pCard->Field(6), "") &&
                mol->find_residue(format, pCard->Field(5), pCard->Field(4),
                atoi(pCard->Field(6)), pCard->Field(7), FstIndex, FstRes)) {
                 Insert_a_Site(pCard->Field(2), FstIndex, FstRes);
            }
            if (strcmp(pCard->Field(8), "") && strcmp(pCard->Field(10), "") &&
                mol->find_residue(format, pCard->Field(9), pCard->Field(8),
                atoi(pCard->Field(10)), pCard->Field(11), FstIndex, FstRes)) {
                 Insert_a_Site(pCard->Field(2), FstIndex, FstRes);
            }
            if (strcmp(pCard->Field(12), "") && strcmp(pCard->Field(14), "") &&
                mol->find_residue(format, pCard->Field(13), pCard->Field(12),
                atoi(pCard->Field(14)), pCard->Field(15), FstIndex, FstRes)) {
                 Insert_a_Site(pCard->Field(2), FstIndex, FstRes);
            }
            if (strcmp(pCard->Field(16), "") && strcmp(pCard->Field(18), "") &&
                mol->find_residue(format, pCard->Field(17), pCard->Field(16),
                atoi(pCard->Field(18)), pCard->Field(19), FstIndex, FstRes)) {
                 Insert_a_Site(pCard->Field(2), FstIndex, FstRes);
            }
            pCard = pCard->Next();
       }
       _CardInfo[SITE_TOKEN-1].clear_Cards();

       pCard = _CardInfo[MODRES_TOKEN-1].Head();
       while (pCard) {
            if (strcmp(pCard->Field(2), "") && strcmp(pCard->Field(3), "") &&
                strcmp(pCard->Field(4), "") && mol->find_residue(format,
                       pCard->Field(3), pCard->Field(2), atoi(pCard->Field(4)),
                       pCard->Field(5), FstIndex, FstRes)) {
                 Insert_a_Modres(pCard->Field(1), FstIndex, FstRes, pCard->Field(6),
                       pCard->Field(7));
            }
            pCard = pCard->Next();
       }
       _CardInfo[MODRES_TOKEN-1].clear_Cards();

       if (format != NDB_FILE_FORMAT_NDB) return;

       pCard = _CardInfo[MISMAT_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_ndb_residue(pCard->Field(2), pCard->Field(3),
                   atoi(pCard->Field(4)), "", FstIndex, FstRes) &&
                mol->find_ndb_residue(pCard->Field(5), pCard->Field(6),
                   atoi(pCard->Field(7)), "", SndIndex, SndRes)) {
                 Insert_a_Mismat(FstIndex, FstRes, SndIndex, SndRes);
            }
            pCard = pCard->Next();
       }
       _CardInfo[MISMAT_TOKEN-1].clear_Cards();

       pCard = _CardInfo[BSPAIR_TOKEN-1].Head();
       while (pCard) {
            get_bspair_second_chain(pCard->Field(6), pCard->Field(8), pCard->Field(10),
                    snd_chainid, snd_resnum, symmetry);
            if (mol->find_ndb_residue(pCard->Field(2), pCard->Field(3),
                   atoi(pCard->Field(4)), "", FstIndex, FstRes) &&
                mol->find_ndb_residue(snd_chainid, pCard->Field(7),
                   snd_resnum, "", SndIndex, SndRes)) {
                 Insert_a_Bspair(pCard->Field(5), FstIndex, FstRes, pCard->Field(9),
                       SndIndex, SndRes, symmetry, pCard->Field(11));
            }
            pCard = pCard->Next();
       }
       _CardInfo[BSPAIR_TOKEN-1].clear_Cards();

       pCard = _CardInfo[MODIFB_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_ndb_residue(pCard->Field(4), pCard->Field(5),
                   atoi(pCard->Field(6)), "", FstIndex, FstRes) &&
                mol->find_ndb_residue(pCard->Field(8), pCard->Field(9),
                   atoi(pCard->Field(10)), "", SndIndex, SndRes)) {
                 Insert_a_Modifb(pCard->Field(2), pCard->Field(3), FstIndex, FstRes,
                     pCard->Field(7), SndIndex, SndRes, pCard->Field(11));
            }
            pCard = pCard->Next();
       }
       _CardInfo[MODIFB_TOKEN-1].clear_Cards();

       pCard = _CardInfo[MODIFP_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_ndb_residue(pCard->Field(4), pCard->Field(5),
                   atoi(pCard->Field(6)), "", FstIndex, FstRes) &&
                mol->find_ndb_residue(pCard->Field(8), pCard->Field(9),
                   atoi(pCard->Field(10)), "", SndIndex, SndRes)) {
                 Insert_a_Modifp(pCard->Field(2), pCard->Field(3), FstIndex, FstRes,
                     pCard->Field(7), SndIndex, SndRes, pCard->Field(11));
            }
            pCard = pCard->Next();
       }
       _CardInfo[MODIFP_TOKEN-1].clear_Cards();

       pCard = _CardInfo[MODIFS_TOKEN-1].Head();
       while (pCard) {
            if (mol->find_ndb_residue(pCard->Field(4), pCard->Field(5),
                   atoi(pCard->Field(6)), "", FstIndex, FstRes) &&
                mol->find_ndb_residue(pCard->Field(8), pCard->Field(9),
                   atoi(pCard->Field(10)), "", SndIndex, SndRes)) {
                 Insert_a_Modifs(pCard->Field(2), pCard->Field(3), FstIndex, FstRes,
                     pCard->Field(7), SndIndex, SndRes, pCard->Field(11),
                     pCard->Field(12));
            }
            pCard = pCard->Next();
       }
       _CardInfo[MODIFS_TOKEN-1].clear_Cards();
}

void _MAXIT::output_structural_features(const int format)
{
       if (_num_mol == 0 || _molecules == NULL) return;

       _MOLECULE *mol = _molecules[0];
       char sheetID[4], SiteID[10];
       int serial_helix = 0, serial_turn = 0, serial_sheet = 1;
       int i = 0, j = 0, length = 0, serial_no = 0, siteId = 0;
       One_Card_Info_Format *pCard = NULL;
       _HELIX *helix = NULL;
       _TURN *turn = NULL;
       _FIELD *Init = NULL, *End = NULL, *Cur = NULL, *Prev = NULL;
       _CHAIN *ch1 = NULL, *ch2 = NULL, *ch3 = NULL, *ch4 = NULL;
       _CHAIN *chain = mol->GetFirstChain();
       while (chain) {
            for (j = 0; j < chain->n_helix(); j++) {
                 pCard = _CardInfo[HELIX_TOKEN-1].
                         add_a_new_card(NdbToken[HELIX_TOKEN-1], 0);
                 serial_helix++;
                 pCard->AddElementToField(serial_helix, 1);
                 helix = chain->helix(j);
                 pCard->AddElementToField(helix->helixID, 2);
                 pCard->AddElementToField(helix->helixClass, 11);
                 pCard->AddElementToField(helix->comment, 12);
                 length = helix->endRes - helix->initRes + 1;
                 pCard->AddElementToField(length, 13);
                 Init = chain->SeqResIndex(helix->initRes);
                 End  = chain->SeqResIndex(helix->endRes);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(chain->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[4], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[3], 7);
                      pCard->AddElementToField(chain->PDB_ChainID(), 8);
                      pCard->AddElementToField(End->Field[4], 9);
                      pCard->AddElementToField(End->InsCode, 10);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(chain->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[2], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[0], 7);
                      pCard->AddElementToField(chain->ChainID(), 8);
                      pCard->AddElementToField(End->Field[2], 9);
                      pCard->AddElementToField(End->InsCode, 10);
                 }
            }

            for (j = 0; j < chain->n_turn(); j++) {
                 pCard = _CardInfo[TURN_TOKEN-1].
                         add_a_new_card(NdbToken[TURN_TOKEN-1], 0);
                 serial_turn++;
                 pCard->AddElementToField(serial_turn, 1);
                 turn = chain->turn(j);
                 pCard->AddElementToField(turn->turnID, 2);
                 pCard->AddElementToField(turn->comment, 11);
                 Init = chain->SeqResIndex(turn->initRes);
                 End  = chain->SeqResIndex(turn->endRes);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(chain->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[4], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[3], 7);
                      pCard->AddElementToField(chain->PDB_ChainID(), 8);
                      pCard->AddElementToField(End->Field[4], 9);
                      pCard->AddElementToField(End->InsCode, 10);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(chain->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[2], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[0], 7);
                      pCard->AddElementToField(chain->ChainID(), 8);
                      pCard->AddElementToField(End->Field[2], 9);
                      pCard->AddElementToField(End->InsCode, 10);
                 }
            }
            chain = mol->GetNextChain();
       }

       strcpy(sheetID, "xxx");
       for (i = 0; i < _n_sheet; i++) {
            ch1 = mol->GetIndexChain(_sheet[i]->initIndex);
            ch2 = mol->GetIndexChain(_sheet[i]->endIndex);
            ch3 = mol->GetIndexChain(_sheet[i]->curIndex);
            ch4 = mol->GetIndexChain(_sheet[i]->prevIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_sheet[i]->initRes);
            End  = ch2->SeqResIndex(_sheet[i]->endRes);
            if (!Init || !End) continue;

            Cur = NULL; Prev = NULL;
            if (ch3) Cur  = ch3->SeqResIndex(_sheet[i]->curRes);
            if (ch4) Prev = ch4->SeqResIndex(_sheet[i]->prevRes);

            pCard = _CardInfo[SHEET_TOKEN-1].
                    add_a_new_card(NdbToken[SHEET_TOKEN-1], 0);
            if (strcmp(_sheet[i]->sheetID, sheetID)) {
                 strcpy(sheetID, _sheet[i]->sheetID);
                 serial_sheet = 1;
            } else serial_sheet++;
            pCard->AddElementToField(serial_sheet, 1);
            pCard->AddElementToField(_sheet[i]->sheetID, 2);
            pCard->AddElementToField(_sheet[i]->numStrands, 3);
            pCard->AddElementToField(_sheet[i]->sense, 12);
            if (Cur && Prev) {
                 pCard->AddElementToField(_sheet[i]->curAtom, 13);
                 pCard->AddElementToField(_sheet[i]->prevAtom, 18);
            }
            if (format == NDB_FILE_FORMAT_PDB) {
                 pCard->AddElementToField(Init->Field[3], 4);
                 pCard->AddElementToField(ch1->PDB_ChainID(), 5);
                 pCard->AddElementToField(Init->Field[4], 6);
                 pCard->AddElementToField(Init->InsCode, 7);
                 pCard->AddElementToField(End->Field[3], 8);
                 pCard->AddElementToField(ch2->PDB_ChainID(), 9);
                 pCard->AddElementToField(End->Field[4], 10);
                 pCard->AddElementToField(End->InsCode, 11);
                 if (Cur && Prev) {
                      pCard->AddElementToField(Cur->Field[3], 14);
                      pCard->AddElementToField(ch3->PDB_ChainID(), 15);
                      pCard->AddElementToField(Cur->Field[4], 16);
                      pCard->AddElementToField(Cur->InsCode, 17);
                      pCard->AddElementToField(Prev->Field[3], 19);
                      pCard->AddElementToField(ch4->PDB_ChainID(), 20);
                      pCard->AddElementToField(Prev->Field[4], 21);
                      pCard->AddElementToField(Prev->InsCode, 22);
                 }
            } else if (format == NDB_FILE_FORMAT_NDB) {
                 pCard->AddElementToField(Init->Field[0], 4);
                 pCard->AddElementToField(ch1->ChainID(), 5);
                 pCard->AddElementToField(Init->Field[2], 6);
                 pCard->AddElementToField(Init->InsCode, 7);
                 pCard->AddElementToField(End->Field[0], 8);
                 pCard->AddElementToField(ch2->ChainID(), 9);
                 pCard->AddElementToField(End->Field[2], 10);
                 pCard->AddElementToField(End->InsCode, 11);
                 if (Cur && Prev) {
                      pCard->AddElementToField(Cur->Field[0], 14);
                      pCard->AddElementToField(ch3->ChainID(), 15);
                      pCard->AddElementToField(Cur->Field[2], 16);
                      pCard->AddElementToField(Cur->InsCode, 17);
                      pCard->AddElementToField(Prev->Field[0], 19);
                      pCard->AddElementToField(ch4->ChainID(), 20);
                      pCard->AddElementToField(Prev->Field[2], 21);
                      pCard->AddElementToField(Prev->InsCode, 22);
                 }
            }
       }

       for (i = 0; i < _n_ssbond; i++) {
            ch1 = mol->GetIndexChain(_ssbond[i]->FstIndex);
            ch2 = mol->GetIndexChain(_ssbond[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_ssbond[i]->FstRes);
            End  = ch2->SeqResIndex(_ssbond[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[SSBOND_TOKEN-1].
                         add_a_new_card(NdbToken[SSBOND_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 pCard->AddElementToField(_ssbond[i]->SymOP_1, 10);
                 pCard->AddElementToField(_ssbond[i]->SymOP_2, 11);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], 2);
                      pCard->AddElementToField(ch1->PDB_ChainID(), 3);
                      pCard->AddElementToField(Init->Field[4], 4);
                      pCard->AddElementToField(Init->InsCode, 5);
                      pCard->AddElementToField(End->Field[3], 6);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 7);
                      pCard->AddElementToField(End->Field[4], 8);
                      pCard->AddElementToField(End->InsCode, 9);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], 2);
                      pCard->AddElementToField(ch1->ChainID(), 3);
                      pCard->AddElementToField(Init->Field[2], 4);
                      pCard->AddElementToField(Init->InsCode, 5);
                      pCard->AddElementToField(End->Field[0], 6);
                      pCard->AddElementToField(ch2->ChainID(), 7);
                      pCard->AddElementToField(End->Field[2], 8);
                      pCard->AddElementToField(End->InsCode, 9);
                 }
            }
       }

       for (i = 0; i < _n_link; i++) {
            ch1 = mol->GetIndexChain(_link[i]->FstIndex);
            ch2 = mol->GetIndexChain(_link[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_link[i]->FstRes);
            End  = ch2->SeqResIndex(_link[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[LINK_TOKEN-1].
                         add_a_new_card(NdbToken[LINK_TOKEN-1], 0);
                 pCard->AddElementToField(_link[i]->FstAtom, 1);
                 pCard->AddElementToField(_link[i]->altLoc1, 2);
                 pCard->AddElementToField(Init->Field[3], 3);
                 pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                 pCard->AddElementToField(Init->Field[4], 5);
                 pCard->AddElementToField(Init->InsCode, 6);
                 pCard->AddElementToField(_link[i]->SndAtom, 7);
                 pCard->AddElementToField(_link[i]->altLoc2, 8);
                 pCard->AddElementToField(End->Field[3], 9);
                 pCard->AddElementToField(ch2->PDB_ChainID(), 10);
                 pCard->AddElementToField(End->Field[4], 11);
                 pCard->AddElementToField(End->InsCode, 12);
                 pCard->AddElementToField(_link[i]->SymOP_1, 13);
                 pCard->AddElementToField(_link[i]->SymOP_2, 14);
            }
       }

       for (i = 0; i < _n_hydbnd; i++) {
            ch1 = mol->GetIndexChain(_hydbnd[i]->FstIndex);
            ch2 = mol->GetIndexChain(_hydbnd[i]->SndIndex);
            ch3 = mol->GetIndexChain(_hydbnd[i]->H_Index);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_hydbnd[i]->FstRes);
            End  = ch2->SeqResIndex(_hydbnd[i]->SndRes);
            Cur  = NULL;
            if (ch3) Cur = ch3->SeqResIndex(_hydbnd[i]->H_Res);
            if (Init && End) {
                 pCard = _CardInfo[HYDBND_TOKEN-1].
                         add_a_new_card(NdbToken[HYDBND_TOKEN-1], 0);
                 pCard->AddElementToField(_hydbnd[i]->FstAtom, 1);
                 pCard->AddElementToField(_hydbnd[i]->altLoc1, 2);
                 pCard->AddElementToField(_hydbnd[i]->H_Atom, 7);
                 pCard->AddElementToField(_hydbnd[i]->altLocH, 8);
                 pCard->AddElementToField(_hydbnd[i]->SndAtom, 12);
                 pCard->AddElementToField(_hydbnd[i]->altLoc2, 13);
                 pCard->AddElementToField(_hydbnd[i]->SymOP_1, 18);
                 pCard->AddElementToField(_hydbnd[i]->SymOP_2, 19);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[4], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      if (Cur) {
                           pCard->AddElementToField(ch3->PDB_ChainID(), 10);
                           pCard->AddElementToField(Cur->Field[4], 11);
                           pCard->AddElementToField(Cur->InsCode, 12);
                      }
                      pCard->AddElementToField(End->Field[3], 14);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 15);
                      pCard->AddElementToField(End->Field[4], 16);
                      pCard->AddElementToField(End->InsCode, 17);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(ch1->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[2], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      if (Cur) {
                           pCard->AddElementToField(ch3->ChainID(), 10);
                           pCard->AddElementToField(Cur->Field[2], 11);
                           pCard->AddElementToField(Cur->InsCode, 12);
                      }
                      pCard->AddElementToField(End->Field[0], 14);
                      pCard->AddElementToField(ch2->ChainID(), 15);
                      pCard->AddElementToField(End->Field[2], 16);
                      pCard->AddElementToField(End->InsCode, 17);
                 }
            }
       }

       for (i = 0; i < _n_sltbrg; i++) {
            ch1 = mol->GetIndexChain(_sltbrg[i]->FstIndex);
            ch2 = mol->GetIndexChain(_sltbrg[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_sltbrg[i]->FstRes);
            End  = ch2->SeqResIndex(_sltbrg[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[SLTBRG_TOKEN-1].
                         add_a_new_card(NdbToken[SLTBRG_TOKEN-1], 0);
                 pCard->AddElementToField(_sltbrg[i]->FstAtom, 1);
                 pCard->AddElementToField(_sltbrg[i]->altLoc1, 2);
                 pCard->AddElementToField(_sltbrg[i]->SndAtom, 7);
                 pCard->AddElementToField(_sltbrg[i]->altLoc2, 8);
                 pCard->AddElementToField(_sltbrg[i]->SymOP_1, 13);
                 pCard->AddElementToField(_sltbrg[i]->SymOP_2, 14);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[4], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[3], 9);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 10);
                      pCard->AddElementToField(End->Field[4], 11);
                      pCard->AddElementToField(End->InsCode, 12);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(ch1->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[2], 5);
                      pCard->AddElementToField(Init->InsCode, 6);
                      pCard->AddElementToField(End->Field[0], 9);
                      pCard->AddElementToField(ch2->ChainID(), 10);
                      pCard->AddElementToField(End->Field[2], 11);
                      pCard->AddElementToField(End->InsCode, 12);
                 }
            }
       }

       serial_no = 0;
       strcpy(SiteID, "XXXXX");
       for (i = 0; i < _n_site; i++) {
            siteId = 0;
            pCard = NULL;
            for (j = 0; j < _site[i]->numRes; j++) {
                 ch1 = mol->GetIndexChain(_site[i]->initIndex[j]);
                 if (!ch1) continue;
                 Init = ch1->SeqResIndex(_site[i]->initRes[j]);
                 if (!Init) continue;

                 if (strcmp(SiteID, _site[i]->SiteID)) {
                      serial_no = 0;
                      strcpy(SiteID, _site[i]->SiteID);
                 }

                 if (siteId == 0) {
                      pCard = _CardInfo[SITE_TOKEN-1].
                              add_a_new_card(NdbToken[SITE_TOKEN-1], 0);
                      serial_no++;
                      pCard->AddElementToField(serial_no, 1);
                      pCard->AddElementToField(_site[i]->SiteID, 2);
                      pCard->AddElementToField(_site[i]->numRes, 3);
                 }
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(Init->Field[3], siteId * 4 + 4);
                      pCard->AddElementToField(ch1->PDB_ChainID(), siteId * 4 + 5);
                      pCard->AddElementToField(Init->Field[4], siteId * 4 + 6);
                      pCard->AddElementToField(Init->InsCode, siteId * 4 + 7);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(Init->Field[0], siteId * 4 + 4);
                      pCard->AddElementToField(ch1->ChainID(), siteId * 4 + 5);
                      pCard->AddElementToField(Init->Field[2], siteId * 4 + 6);
                      pCard->AddElementToField(Init->InsCode, siteId * 4 + 7);
                 }
                 siteId++;
                 if (siteId == 4) siteId = 0;
            }
       }
 
       serial_no = 0;
       for (i = 0; i < _n_modres; i++) {
            ch1 = mol->GetIndexChain(_modres[i]->FstIndex);
            if (!ch1) continue;
            Init = ch1->SeqResIndex(_modres[i]->FstRes);
            if (!Init) continue;

            pCard = _CardInfo[MODRES_TOKEN-1].
                    add_a_new_card(NdbToken[MODRES_TOKEN-1], 0);
            pCard->AddElementToField(_modres[i]->PDB_ID, 1);
            pCard->AddElementToField(_modres[i]->Standard_Name, 6);
            pCard->AddElementToField(_modres[i]->details, 7);
            serial_no++;
            pCard->AddElementToField(serial_no, 8);
            if (format == NDB_FILE_FORMAT_PDB) {
                 pCard->AddElementToField(Init->Field[3], 2);
                 pCard->AddElementToField(ch1->PDB_ChainID(), 3);
                 pCard->AddElementToField(Init->Field[4], 4);
                 pCard->AddElementToField(Init->InsCode, 5);
            } else if (format == NDB_FILE_FORMAT_NDB) {
                 pCard->AddElementToField(Init->Field[0], 2);
                 pCard->AddElementToField(ch1->ChainID(), 3);
                 pCard->AddElementToField(Init->Field[2], 4);
                 pCard->AddElementToField(Init->InsCode, 5);
            }
       }

       for (i = 0; i < _n_het; i++) {
            ch1 = _molecules[_rep_mol]->GetIndexChain(_het[i]->initIndex);
            if (!ch1) continue;
            Init = ch1->SeqResIndex(_het[i]->initRes);
            if (!Init) continue;

            pCard = _CardInfo[HET_TOKEN-1].
                    add_a_new_card(NdbToken[HET_TOKEN-1], 0);
            if (format == NDB_FILE_FORMAT_PDB) {
                 pCard->AddElementToField(Init->Field[3], 1);
                 pCard->AddElementToField(ch1->PDB_ChainID(), 2);
                 pCard->AddElementToField(Init->Field[4], 3);
                 pCard->AddElementToField(Init->InsCode, 4);
            } else if (format == NDB_FILE_FORMAT_NDB) {
                 pCard->AddElementToField(Init->Field[0], 1);
                 pCard->AddElementToField(ch1->ChainID(), 2);
                 pCard->AddElementToField(Init->Field[2], 3);
                 pCard->AddElementToField(Init->InsCode, 4);
            }
            pCard->AddElementToField(_het[i]->numAtoms, 5);
       }

       serial_no = 0;
       for (i = 0; i < _n_mismat; i++) {
            ch1 = mol->GetIndexChain(_mismat[i]->FstIndex);
            ch2 = mol->GetIndexChain(_mismat[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_mismat[i]->FstRes);
            End  = ch2->SeqResIndex(_mismat[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[MISMAT_TOKEN-1].
                         add_a_new_card(NdbToken[MISMAT_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(ch1->PDB_ChainID(), 2);
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(Init->Field[4], 4);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 5);
                      pCard->AddElementToField(End->Field[3], 6);
                      pCard->AddElementToField(End->Field[4], 7);

                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(ch1->ChainID(), 2);
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(Init->Field[2], 4);
                      pCard->AddElementToField(ch2->ChainID(), 5);
                      pCard->AddElementToField(End->Field[0], 6);
                      pCard->AddElementToField(End->Field[2], 7);
                 }
            }
       }
       
       serial_no = 0;
       for (i = 0; i < _n_bspair; i++) {
            ch1 = mol->GetIndexChain(_bspair[i]->FstIndex);
            ch2 = mol->GetIndexChain(_bspair[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_bspair[i]->FstRes);
            End  = ch2->SeqResIndex(_bspair[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[BSPAIR_TOKEN-1].
                         add_a_new_card(NdbToken[BSPAIR_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(ch1->PDB_ChainID(), 2);
                      pCard->AddElementToField(Init->Field[3], 3);
                      pCard->AddElementToField(Init->Field[4], 4);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 6);
                      pCard->AddElementToField(End->Field[3], 7);
                      pCard->AddElementToField(End->Field[4], 8);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(ch1->ChainID(), 2);
                      pCard->AddElementToField(Init->Field[0], 3);
                      pCard->AddElementToField(Init->Field[2], 4);
                      pCard->AddElementToField(ch2->ChainID(), 6);
                      pCard->AddElementToField(End->Field[0], 7);
                      pCard->AddElementToField(End->Field[2], 8);
                 }
                 pCard->AddElementToField(_bspair[i]->FstAtom, 5);
                 pCard->AddElementToField(_bspair[i]->SndAtom, 9);
                 pCard->AddElementToField("A", 10);
                 pCard->AddElementToField(_bspair[i]->Type, 11);

                 if (strcmp(_bspair[i]->Asym_or_Gen, "")) {
                      pCard->AddElementToField("S", 10);
                      for (j = 0; j < _n_stbiol; j++) {
                           if (!_stbiol[j]) continue;
                           if (_stbiol[j]->Asym_ID == ch2->ChainID() &&
                               !strcmp(_stbiol[j]->Symmetry, _bspair[i]->Asym_or_Gen)) {
                                pCard->AddElementToField(_stbiol[j]->NDB_Strand_ID.Text(), 6);
                                break;
                           }
                      }
                 }
            }
       }
       
       serial_no = 0;
       for (i = 0; i < _n_modifb; i++) {
            ch1 = mol->GetIndexChain(_modifb[i]->FstIndex);
            ch2 = mol->GetIndexChain(_modifb[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_modifb[i]->FstRes);
            End  = ch2->SeqResIndex(_modifb[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[MODIFB_TOKEN-1].
                         add_a_new_card(NdbToken[MODIFB_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 pCard->AddElementToField(_modifb[i]->Name, 2);
                 pCard->AddElementToField(_modifb[i]->FstAtom, 3);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[3], 5);
                      pCard->AddElementToField(Init->Field[4], 6);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 8);
                      pCard->AddElementToField(End->Field[3], 9);
                      pCard->AddElementToField(End->Field[4], 10);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(ch1->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[0], 5);
                      pCard->AddElementToField(Init->Field[2], 6);
                      pCard->AddElementToField(ch2->ChainID(), 8);
                      pCard->AddElementToField(End->Field[0], 9);
                      pCard->AddElementToField(End->Field[2], 10);
                 }
                 pCard->AddElementToField(_modifb[i]->SndAtom, 7);
                 pCard->AddElementToField(_modifb[i]->Replaced_Atom, 11);
            }
       }
       
       serial_no = 0;
       for (i = 0; i < _n_modifp; i++) {
            ch1 = mol->GetIndexChain(_modifp[i]->FstIndex);
            ch2 = mol->GetIndexChain(_modifp[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_modifp[i]->FstRes);
            End  = ch2->SeqResIndex(_modifp[i]->SndRes);
            if (Init && End) {
                pCard = _CardInfo[MODIFP_TOKEN-1].
                        add_a_new_card(NdbToken[MODIFP_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 pCard->AddElementToField(_modifp[i]->Name, 2);
                 pCard->AddElementToField(_modifp[i]->FstAtom, 3);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[3], 5);
                      pCard->AddElementToField(Init->Field[4], 6);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 8);
                      pCard->AddElementToField(End->Field[3], 9);
                      pCard->AddElementToField(End->Field[4], 10);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(ch1->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[0], 5);
                      pCard->AddElementToField(Init->Field[2], 6);
                      pCard->AddElementToField(ch2->ChainID(), 8);
                      pCard->AddElementToField(End->Field[0], 9);
                      pCard->AddElementToField(End->Field[2], 10);
                 }
                 pCard->AddElementToField(_modifp[i]->SndAtom, 7);
                 pCard->AddElementToField(_modifp[i]->Replaced_Atom, 11);
            }
       }
       
       serial_no = 0;
       for (i = 0; i < _n_modifs; i++) {
            ch1 = mol->GetIndexChain(_modifs[i]->FstIndex);
            ch2 = mol->GetIndexChain(_modifs[i]->SndIndex);
            if (!ch1 || !ch2) continue;
            Init = ch1->SeqResIndex(_modifs[i]->FstRes);
            End  = ch2->SeqResIndex(_modifs[i]->SndRes);
            if (Init && End) {
                 pCard = _CardInfo[MODIFS_TOKEN-1].
                         add_a_new_card(NdbToken[MODIFS_TOKEN-1], 0);
                 serial_no++;
                 pCard->AddElementToField(serial_no, 1);
                 pCard->AddElementToField(_modifs[i]->Name, 2);
                 pCard->AddElementToField(_modifs[i]->FstAtom, 3);
                 if (format == NDB_FILE_FORMAT_PDB) {
                      pCard->AddElementToField(ch1->PDB_ChainID(), 4);
                      pCard->AddElementToField(Init->Field[3], 5);
                      pCard->AddElementToField(Init->Field[4], 6);
                      pCard->AddElementToField(ch2->PDB_ChainID(), 8);
                      pCard->AddElementToField(End->Field[3], 9);
                      pCard->AddElementToField(End->Field[4], 10);
                 } else if (format == NDB_FILE_FORMAT_NDB) {
                      pCard->AddElementToField(ch1->ChainID(), 4);
                      pCard->AddElementToField(Init->Field[0], 5);
                      pCard->AddElementToField(Init->Field[2], 6);
                      pCard->AddElementToField(ch2->ChainID(), 8);
                      pCard->AddElementToField(End->Field[0], 9);
                      pCard->AddElementToField(End->Field[2], 10);
                 }
                 pCard->AddElementToField(_modifs[i]->SndAtom, 7);
                 pCard->AddElementToField(_modifs[i]->Replaced_Atom, 11);
                 pCard->AddElementToField(_modifs[i]->Sugar_Name, 12);
            }
       }
}
/*
void _MAXIT::update_pdb_and_pub_numbers()
{
       if (_num_mol == 0 || _molecules == NULL) return;
       if (_Num_NPdb == 0 || _NPdb == NULL) return;

       _CHAIN *chain = NULL;
       for (int m = 0; m < _num_mol; m++) {
            chain = _molecules[m]->GetFirstChain();
            while (chain) {
                 chain->update_pdb_and_pub_numbers(_Num_NPdb, _NPdb);
                 chain = _molecules[m]->GetNextChain();
            }
       }
}
*/
void _MAXIT::get_refn_card()
{
       int i, ref_id, refn_id, is_epublished;
       char buffer[1000];
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;
       ref_trans_format *ref = NULL;

       ref_id = find_jrnl_id("REF");
       refn_id = find_jrnl_id("REFN");
       
       qCard = _JrnlCardInfo[ref_id].Head();
       while (qCard) {
            if (!strcasecmp(qCard->Field(4), "Proc.Nat.Acad.Sci.USA")) {
                 qCard->AddElementToField("Proc.Natl.Acad.Sci.USA", 4);
            }
            qCard = qCard->Next();
       }

       qCard = _JrnlCardInfo[ref_id].Head();     
       while (qCard) {
            pCard = _JrnlCardInfo[refn_id].Head();
            while (pCard) {
                 if (!strcmp(pCard->Field(1), qCard->Field(1))) break;
                 pCard = pCard->Next();
            }
            if (pCard) {
                 if (strcmp(pCard->Field(3), "")) {
                      qCard = qCard->Next();
                      continue;
                 }
            } else {
                 pCard = _JrnlCardInfo[refn_id].add_a_new_card(JrnlToken[refn_id], 1);
                 pCard->AddElementToField(qCard->Field(1), 1);
            }

            is_epublished = 1;
            if (strcmp(qCard->Field(6), "") && strcmp(qCard->Field(7), ""))
                 is_epublished = 0;
            ref = find_ref(qCard->Field(4), is_epublished);
            if (ref) {
                 // for (i = 3; i < JrnlToken[refn_id].NumField; i++) {
                 for (i = 3; i < 9; i++) {
                      if (!strcmp(pCard->Field(i), "")) {
                           pCard->AddElementToField(ref->refn[i-3], i);
                      }
                 }
                 if (strcasecmp(qCard->Field(4), ref->ref)) {
                      sprintf(buffer, "There are space differences between '%s' and '%s'",
                                 qCard->Field(4), ref->ref);
                      ndb_log_message(NDB_MSG_WARN, "%s\n", buffer);
                 }
            } else if (strcasecmp(qCard->Field(4), "To be Published")) {
                 ndb_log_message(NDB_MSG_WARN, "Journal %s did not exist in dictionary\n", qCard->Field(4));
            }
            qCard = qCard->Next();
       }
}

void _MAXIT::get_bspair_second_chain(const char *old_chnid, const char *old_num,
         const char *old_sym, char *new_chnid, int &new_num, char *new_sym)
{
       int i;
       strcpy(new_chnid, old_chnid);
       new_num = atoi(old_num);
       strcpy(new_sym, "");
       if (!strcmp(old_sym, "A")) return;

       for (i = 0; i < _n_stbiol; i++) {
            if (!_stbiol[i]) continue;
            if (_stbiol[i]->NDB_Strand_ID.Text() == old_chnid &&
                 strcmp(_stbiol[i]->Symmetry, "1_555")) break;
       }
       if (i < _n_stbiol) {
            strcpy(new_chnid, _stbiol[i]->Asym_ID.Text());
            strcpy(new_sym, _stbiol[i]->Symmetry);
            new_num = atoi(old_num) - _stbiol[i]->abrn + _stbiol[i]->bbrn;
       }
}

void _MAXIT::generate_ncs_strands()
{
       int card_id, successful;
       double mat[3][4];
       One_Card_Info_Format *pCard = NULL;

       if (_num_mol == 0 || _molecules == NULL) return;

       card_id = find_card_id("NCSGEN");
       if (_CardInfo[card_id].Head() == NULL ||
           _CardInfo[MTRIX_TOKEN-1].Head() == NULL) return;

       pCard = _CardInfo[MTRIX_TOKEN-1].Head();
       while (pCard) {
            if (!strcmp(pCard->Field(6), "")) break;
            pCard = pCard->Next();
       }
       if (pCard == NULL) return;

       successful = 0;
       pCard = _CardInfo[card_id].Head();
       while (pCard) {
            if (strcmp(pCard->Field(2), "") && strcmp(pCard->Field(5), "")) {
                 if (get_matrix(mat, atoi(pCard->Field(2)))) {
                      if (_molecules[0]->symmetry_related_chain(atoi(pCard->Field(7)),
                            pCard->Field(3), pCard->Field(5), pCard->Field(6), mat))
                           successful = 1;
                 }
            }
            pCard = pCard->Next();
       }
       if (successful) {
            if (_stbiol) {
                 delete [] _stbiol;
                 _stbiol = NULL;
            }
            _n_stbiol = 0;
            match_stbiol_with_molecules();
       }
}

int _MAXIT::get_matrix(double m[3][4], const int serial_no)
{
       int i = 0, j;
       One_Card_Info_Format *pCard = _CardInfo[MTRIX_TOKEN-1].Head();
       while (pCard) {
            if (atoi(pCard->Field(1)) == serial_no) {
                 if (i >= 3) return 0;
                 for (j = 0; j < 4; j++)
                      m[i][j] = atof(pCard->Field(j+2));
                 i++;
            }
            pCard = pCard->Next();
       }
       if (i != 3) return 0;
       else        return 1;
}

void _MAXIT::delete_atoms(const char *filename)
{
       char command[400], line[200], chnid[10], resname[6], inscode[10], *p;
       int i, resnum;
       _RESIDUE *residue = NULL;

       FILE *fp = fopen(filename, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", filename);
            return;
       }
       command[0] = '\0';
       while (!feof(fp)) {
            fgets(line, 199, fp);
            if (feof(fp)) break;
            line[strlen(line)-1] = '\0';
            resnum = strlen(line);
            for (i = 0; i < resnum; i++) {
                 if (line[i] == '=' || line[i] == ',') line[i] = ' ';
            }
            ndb_set_string_to_upper(line);
            strcat(command, " ");
            strcat(command, line);
            ndb_clean_string(command);
            if (strstr(command, "RESIDUE") && strstr(command, "ATOMLIST")) {
                 sscanf(command, "%s %s %s %d %s", line, chnid, resname, &resnum,
                                         inscode);
                 if (!strcmp(chnid, "\"\"") || !strcmp(chnid, "''"))
                      strcpy(chnid, "");
                 if (!strcmp(inscode, "\"\"") || !strcmp(inscode, "''"))
                      strcpy(inscode, "");
                 for (i = 0; i < _num_mol; i++) {
                      residue = _molecules[i]->find_pdb_residue(chnid,
                                           resname, resnum, inscode);
                      p = strstr(command, "ATOMLIST");
                      if (strlen(p) > 8 && residue) {
                           p += 8;
                           while (p) {
                                p = get_word(p, line);
                                residue->delete_a_atom(line);
                           }
                           residue->reorder_atoms();
                      }
                 }
                 strcpy(command, "");
            }
       }
       fclose (fp);
}

void _MAXIT::insert_atoms(const char *filename)
{
       if (_num_mol == 0) return;

       FILE *fp = fopen(filename, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", filename);
            return;
       }
       char CardString[10], PrevSeqNo[10], FieldInfo[MxField][MxLen];
       int i, PrevTokenId, JrnlId, lineno, TokenId;
       _RESIDUE *residue = NULL, *exist = NULL;
       _ATOM *atom = NULL, *tmp = NULL;

       for (i = 0; i < MxField; i++) memset(FieldInfo[i], 0, MxLen);
       residue = new _RESIDUE;
       PrevTokenId = -1;
       JrnlId = -1;
       lineno = 0;
       TokenId = -1;
       strcpy(PrevSeqNo, "xxx");
       do {
            TokenId = get_card(fp, CardString, lineno);
            if (TokenId == -2) break;
            if (!is_atom_card(TokenId) && strcmp(CardString, "ATOM") &&
                 strcmp(CardString, "HETATM")) {
                 if (!strcmp(CardString, "END")) break;
                 end_line(fp); continue;
            }
            if (TokenId == -1) TokenId = ATOMN_TOKEN - 1;
            get_one_line_info(fp, TokenId, PrevTokenId, PrevSeqNo, JrnlId, -1,
                    CardString, FieldInfo, -1, -1, NDB_FILE_FORMAT_PDB, 0);
            residue->insert_a_atom(TokenId , FieldInfo, 1, _error_message);
            for (i = 0; i < 23; i++) FieldInfo[i][0] = '\0';
       } while (!feof(fp));
       fclose (fp);

       exist = NULL;
       atom = residue->GetFirstAtom();
       while (atom) {
            exist = _molecules[0]->find_pdb_residue(atom->chnid(),
                          atom->restype(), atom->resnum(), atom->ins_code());
            if (exist) {
                 tmp = new _ATOM;
                 *tmp = *atom;
                 exist->insert_a_atom(tmp, _error_message);
                 exist->reorder_atoms();
            }
            atom = residue->GetNextAtom();
       }
       delete residue;
}

void _MAXIT::delete_residues(const char *filename)
{
       FILE *fp = fopen(filename, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", filename);
            return;
       }

       char line[200], buffer[10], chnid[10], resname[6], inscode[10];
       int resnum = 0, i = 0;
       _CHAIN *chain = NULL;

       while (!feof(fp)) {
            fgets(line, 199, fp);
            if (feof(fp)) break;
            line[strlen(line)-1] = '\0';
            resnum = strlen(line);
            for (i = 0; i < resnum; i++) {
                 if (line[i] == '=' || line[i] == ',') line[i] = ' ';
            }
            ndb_set_string_to_upper(line);
            ndb_clean_string(line);
            if (strstr(line, "RESIDUE")) {
                 sscanf(line, "%s %s %s %d %s", buffer, chnid, resname, &resnum,
                                         inscode);
                 if (!strcmp(chnid, "\"\"") || !strcmp(chnid, "''"))
                      strcpy(chnid, "");
                 if (!strcmp(inscode, "\"\"") || !strcmp(inscode, "''"))
                      strcpy(inscode, "");
                 for (i = 0; i < _num_mol; i++) {
                      chain = _molecules[i]->GetFirstChain();
                      while (chain) {
                           if (!strcmp(chnid, chain->PDB_ChainID())) {
                                if (chain->delete_a_residue(resname, resnum,
                                      inscode)) break;
                           }
                           chain = _molecules[i]->GetNextChain();
                      }
                 }
            }
       }
       fclose (fp);
}

void _MAXIT::insert_residues(const char *filename)
{
       if (_num_mol == 0) return;

       FILE *fp = fopen(filename, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", filename);
            return;
       }
       char CardString[10], PrevSeqNo[10], FieldInfo[MxField][MxLen], line[200];
       char chnid[10], resname[6], inscode[10], ID[3], NAME[5], CODE[3];
       char ResidueNo[10], ChainId[10], ResidueName[10], InsCode[10];
       int  resnum, Num_Residue, Alloc_Residue, PrevTokenId, JrnlId;
       int  i, lineno, is_first, TokenId, pos, NUM, at_begin;
       _ATOM *atom = NULL;
       _RESIDUE **residue = NULL, **tmp = NULL;
       _CHAIN *chain = NULL;

       for (i = 0; i < MxField; i++) memset(FieldInfo[i], 0, MxLen);
       Num_Residue = 0;
       Alloc_Residue = 0;
       PrevTokenId = -1;
       JrnlId = -1;
       lineno = 0;
       is_first = 0;
       TokenId = -1;
       pos = 0; NUM = 0; at_begin = 0; resnum = 0;

       strcpy(chnid, "");
       strcpy(inscode, "");
       strcpy(inscode, "");
       strcpy(NAME, "");
       strcpy(CODE, "");

       strcpy(PrevSeqNo, "xxx");
       strcpy(ResidueNo, "xxx");
       strcpy(ChainId, "xxx");
       strcpy(ResidueName, "xxx");
       strcpy(InsCode, "xxx");

       do {
            TokenId = get_card(fp, CardString, lineno);
            if (TokenId == -2) break;
            if (!strcmp(CardString, "BEFORE") ||
                !strcmp(CardString, "AFTER")) {
                 if (Num_Residue) {
                      chain = _molecules[0]->GetFirstChain();
                      while (chain) {
                           if (!strcmp(chnid, chain->PDB_ChainID()) &&
                                chain->find_PDB_residue(resname, resnum,
                                inscode, pos)) {
                                for (i = 0; i < Num_Residue; i++) {
                                     if (!i) {
                                          strcpy(ID, chnid); strcpy(NAME, resname);
                                          NUM = resnum; strcpy(CODE, inscode);
                                          at_begin = is_first;
                                     }
                                     if (chain->find_PDB_residue(NAME, NUM, CODE, pos)) {
                                          if (at_begin)
                                               chain->insert_a_residue(residue[i], -1);
                                          else chain->insert_a_residue(residue[i], pos);
                                          atom = residue[i]->GetFirstAtom();
                                          strcpy(ID, atom->chnid());
                                          strcpy(NAME, atom->restype());
                                          NUM = atom->resnum();
                                          strcpy(CODE, atom->ins_code());
                                          at_begin = 0;
                                          residue[i] = NULL;
                                     }
                                }
                                break;
                           }
                           chain = _molecules[0]->GetNextChain();
                      }
                      for (i = 0; i < Num_Residue; i++) {
                           if (residue[i]) {
                                delete residue[i];
                                residue[i] = NULL;
                           }
                      }
                 }
                 Num_Residue = 0;

                 get_one_line(line, fp);
                 line[strlen(line)-1] = '\0';
                 resnum = strlen(line);
                 for (i = 0; i < resnum; i++) {
                      if (line[i] == '=' || line[i] == ',') line[i] = ' ';
                 }
                 ndb_set_string_to_upper(line);
                 ndb_clean_string(line);
                 sscanf(line, "%s %s %d %s", chnid, resname, &resnum, inscode);
                 if (!strcmp(chnid, "\"\"") || !strcmp(chnid, "''"))
                      strcpy(chnid, "");
                 if (!strcmp(inscode, "\"\"") || !strcmp(inscode, "''"))
                      strcpy(inscode, "");
                 if (!strcmp(CardString, "BEFORE")) is_first = 1;
                 if (!strcmp(CardString, "AFTER")) is_first = 0;
                 continue;
            }
            if (!is_atom_card(TokenId) && strcmp(CardString, "ATOM") &&
                 strcmp(CardString, "HETATM")) {
                 if (!strcmp(CardString, "END")) break;
                 end_line(fp); continue;
            }
            if (TokenId == -1) TokenId = ATOMN_TOKEN - 1;
            get_one_line_info(fp, TokenId, PrevTokenId, PrevSeqNo, JrnlId, -1,
                    CardString, FieldInfo, -1, -1, NDB_FILE_FORMAT_PDB, 0);

            if (strcmp(FieldInfo[5], ChainId) ||
                strcmp(FieldInfo[6], ResidueNo) ||
                strcmp(FieldInfo[4], ResidueName) ||
                strcmp(FieldInfo[7], InsCode)) {
                 if (Num_Residue >= Alloc_Residue) {
                      Alloc_Residue +=  10;
                      tmp = residue;
                      residue = new _RESIDUE*[Alloc_Residue];
                      for (i = 0; i < Num_Residue; i++)
                           residue[i] = tmp[i];
                      for (i = Num_Residue; i < Alloc_Residue; i++)
                           residue[i] = NULL;
                      delete [] tmp;
                 }
                 residue[Num_Residue] = new _RESIDUE;
                 residue[Num_Residue]->set_ResName(FieldInfo[4]);
                 residue[Num_Residue]->set_res_no(atoi(FieldInfo[6]));
                 if (strcmp(FieldInfo[15], ""))
                      residue[Num_Residue]->set_pdb_res_no(atoi(FieldInfo[15]));
                 else residue[Num_Residue]->set_pdb_res_no(atoi(FieldInfo[6]));
                 Num_Residue++;
            }
            residue[Num_Residue-1]->insert_a_atom(TokenId , FieldInfo, 1,
                                 _error_message);

            strcpy(ChainId, FieldInfo[5]);
            strcpy(ResidueNo, FieldInfo[6]);
            strcpy(ResidueName, FieldInfo[4]);
            strcpy(InsCode, FieldInfo[7]);
            for (i = 0; i < 23; i++) FieldInfo[i][0] = '\0';
       } while (!feof(fp));
       fclose (fp);

       if (Num_Residue) {
            chain = _molecules[0]->GetFirstChain();
            while (chain) {
                 if (!strcmp(chnid, chain->PDB_ChainID()) &&
                      chain->find_PDB_residue(resname, resnum,
                      inscode, pos)) {
                      for (i = 0; i < Num_Residue; i++) {
                           if (!i) {
                                strcpy(ID, chnid); strcpy(NAME, resname);
                                NUM = resnum; strcpy(CODE, inscode);
                                at_begin = is_first;
                           }
                           if (chain->find_PDB_residue(NAME, NUM, CODE, pos)) {
                                if (at_begin)
                                     chain->insert_a_residue(residue[i], -1);
                                else chain->insert_a_residue(residue[i], pos);
                                atom = residue[i]->GetFirstAtom();
                                strcpy(ID, atom->chnid());
                                strcpy(NAME, atom->restype());
                                NUM = atom->resnum();
                                strcpy(CODE, atom->ins_code());
                                at_begin = 0;
                                residue[i] = NULL;
                           }
                      }
                      break;
                 }
                 chain = _molecules[0]->GetNextChain();
            }
            for (i = 0; i < Num_Residue; i++) {
                 if (residue[i]) {
                      delete residue[i];
                      residue[i] = NULL;
                 }
            }
       }
       delete [] residue;
}

void _MAXIT::replace_residues(const char *filename)
{
       if (_num_mol == 0) return;

       FILE *fp = fopen(filename, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", filename);
            return;
       }
       char CardString[10], PrevSeqNo[10], FieldInfo[MxField][MxLen];
       char ResidueNo[10], ChainId[10], ResidueName[10], InsCode[10];
       int  i, PrevTokenId, JrnlId, lineno, TokenId;
       _ATOM *atom = NULL;
       _RESIDUE *residue = NULL, *exist = NULL;
       
       for (i = 0; i < MxField; i++) memset(FieldInfo[i], 0, MxLen);
       residue = new _RESIDUE;
       PrevTokenId = -1;
       JrnlId = -1;
       lineno = 0;
       TokenId = -1;
       strcpy(PrevSeqNo, "xxx");
       strcpy(ResidueNo, "xxx");
       strcpy(ChainId, "xxx");
       strcpy(ResidueName, "xxx");
       strcpy(InsCode, "xxx");
       do {
            TokenId = get_card(fp, CardString, lineno);
            if (TokenId == -2) break;
            if (!is_atom_card(TokenId) && strcmp(CardString, "ATOM") &&
                 strcmp(CardString, "HETATM")) {
                 if (!strcmp(CardString, "END")) break;
                 end_line(fp); continue;
            }
            if (TokenId == -1) TokenId = ATOMN_TOKEN - 1;
            get_one_line_info(fp, TokenId, PrevTokenId, PrevSeqNo, JrnlId, -1,
                    CardString, FieldInfo, -1, -1, NDB_FILE_FORMAT_PDB, 0);

            if (strcmp(FieldInfo[5], ChainId) ||
                strcmp(FieldInfo[6], ResidueNo) ||
                strcmp(FieldInfo[4], ResidueName) ||
                strcmp(FieldInfo[7], InsCode)) {
                 atom = residue->GetFirstAtom();
                 if (atom) {
                      residue->change_nomenclature(NDB_FILE_FORMAT_PDB, 1, 0, 0);
                      exist = _molecules[0]->find_pdb_residue(atom->chnid(),
                           atom->restype(), atom->resnum(), atom->ins_code());
                      if (exist) exist->replace_residue(residue);
                 }
                 residue->set_ResName(FieldInfo[4]);
                 residue->set_res_no(atoi(FieldInfo[6]));
                 if (strcmp(FieldInfo[15], ""))
                      residue->set_pdb_res_no(atoi(FieldInfo[15]));
                 else residue->set_pdb_res_no(atoi(FieldInfo[6]));
            }
            residue->insert_a_atom(TokenId , FieldInfo, 1, _error_message);

            strcpy(ChainId, FieldInfo[5]);
            strcpy(ResidueNo, FieldInfo[6]);
            strcpy(ResidueName, FieldInfo[4]);
            strcpy(InsCode, FieldInfo[7]);
            for (i = 0; i < 23; i++) FieldInfo[i][0] = '\0';
       } while (!feof(fp));
       fclose (fp);

       atom = residue->GetFirstAtom();
       if (atom) {
            residue->change_nomenclature(NDB_FILE_FORMAT_PDB, 1, 0, 0);
            exist = _molecules[0]->find_pdb_residue(atom->chnid(),
                    atom->restype(), atom->resnum(), atom->ins_code());
            if (exist) exist->replace_residue(residue);
       }

       delete residue;
}

void _MAXIT::set_refine_program(_MAXIT *obj)
{
       One_Card_Info_Format *qCard = obj->_CardInfo[REFMET_TOKEN-1].Head();
       if (qCard && strcmp(qCard->Field(3), "")) {
            One_Card_Info_Format *pCard = _CardInfo[REFMET_TOKEN-1].Head();
            if (!pCard) pCard = _CardInfo[REFMET_TOKEN-1].
                         add_a_new_card(NdbToken[REFMET_TOKEN-1], 0);
            pCard->AddElementToField(qCard->Field(3), 3);
       }
}

void _MAXIT::merge_remarks(_MAXIT *rmk)
{
       int i, j, card_id, temp_id /* , count */ ;
       One_Card_Info_Format *pCard, *qCard;

       temp_id = find_card_id("TMLPTL"); 
       for (i = 0; i < NUM_TOKENS; i++) {
            card_id = find_card_id(merge_tokens[i]);
            if (card_id < 0) continue;
            qCard = rmk->_CardInfo[card_id].Head();
            if (!qCard) continue;
/*
            count = 0;
            while (qCard) {
                 count++;
                 qCard = qCard->Next();
            }
            if (count != 1) continue;

            pCard = _CardInfo[card_id].Head();
            count = 0;
            while (pCard) {
                 count++;
                 pCard = pCard->Next();
            }
            if (count > 1) continue;
*/
            pCard = _CardInfo[card_id].Head();
            while (pCard) pCard = _CardInfo[card_id].delete_a_card(pCard);
            if (!strcmp(merge_tokens[i], "RFTPOS") ||
                !strcmp(merge_tokens[i], "RFMPOS") ||
                !strcmp(merge_tokens[i], "RFLPOS") ||
                !strcmp(merge_tokens[i], "RFTTHR") ||
                !strcmp(merge_tokens[i], "RFMTHR") ||
                !strcmp(merge_tokens[i], "RFLTHR")) {
                 if (temp_id >= 0) {
                      pCard = _CardInfo[temp_id].Head();
                      while (pCard) pCard = _CardInfo[temp_id].delete_a_card(pCard);
                 }
            }

            qCard = rmk->_CardInfo[card_id].Head();
          while (qCard) {
/*
            pCard = _CardInfo[card_id].Head();
            if (!pCard) */ pCard = _CardInfo[card_id].add_a_new_card(NdbToken[card_id], 0);

            for (j = 1; j < pCard->NumField(); j++) {
/*
                 if ((j+1) == NdbToken[card_id].SeqField ||
                     (j+1) == NdbToken[card_id].ConField ||
                     (j+1) == NdbToken[card_id].PdbConField) continue;
*/
                 if (strcmp(qCard->Field(j), ""))
                      pCard->AddElementToField(qCard->Field(j), j);
            }
            qCard = qCard->Next();
          }
       }
}

void _MAXIT::switch_residue_name_from_sequences()
{
       int i;
       _CHAIN *chain = NULL;
       for (i = 0; i < _num_mol; i++) {
            chain = _molecules[i]->GetFirstChain();
            while (chain) {
                 if (chain->chain_type() == ATOMP_TOKEN)
                      chain->correction_residues_name();
                 chain = _molecules[i]->GetNextChain();
            }
       }
}

void _MAXIT::moving_waters()
{
       int i, prev_n_moving_waters = 0;
       _RESIDUE *residue = NULL;

       while (1) {
            calculate_all_contact(3.5, 1);
            if (!_n_moving_waters) break;
            for (i = 0; i < _n_moving_waters; i++) {
                 residue = _molecules[0]->find_ndb_residue(_moving_waters[i]->a_chnid,
                           _moving_waters[i]->a_resnam, _moving_waters[i]->a_resnum, "");
                 if (!residue) continue;
                 residue->convert_between_orthogonal_and_fractional(_cell,
                            NDB_TRANS_ORTHO_TO_FRAC);
                 residue->symmetry_operations(_moving_waters[i]->transl[0],
                               _moving_waters[i]->transl[1], _moving_waters[i]->transl[2],
                               &(_cell->symops[_moving_waters[i]->sym]), 1);
                 residue->convert_between_orthogonal_and_fractional(_cell,
                            NDB_TRANS_FRAC_TO_ORTHO);
            }
            if (prev_n_moving_waters == _n_moving_waters) break;
            prev_n_moving_waters = _n_moving_waters;
       }
}

void _MAXIT::check_chnids()
{
       int i, num = 0;
       char chnid[5];
       _CHAIN *chain = NULL;
       One_Card_Info_Format *pCard = NULL;

       strcpy(chnid, "XXX");
       pCard = _CardInfo[SEQRES_TOKEN-1].Head();
       while (pCard) {
            if (strcmp(chnid, pCard->Field(2))) {
                 strcpy(chnid, pCard->Field(2));
                 num++;
            }
            pCard = pCard->Next();
       }
       if (num != 1 || !strcmp(chnid, "")) return;

       for (i = 0; i < _num_mol; i++) {
            chain = _molecules[i]->GetFirstChain();
            while (chain) {
                 if (chain->chain_type() != ATOMN_TOKEN &&
                     chain->chain_type() != ATOMP_TOKEN) {
                      chain = _molecules[i]->GetNextChain();
                      continue;
                 }
                 if (!strcmp(chain->ChainID(), ""))
                      chain->set_ChainID(chnid);
                 chain = _molecules[i]->GetNextChain();
            }
       }
}

void _MAXIT::change_coordinates_symm(const char *support_file)
{
       unsigned int i;
       int op = 0, lx = 0, ly = 0, lz = 0, flag_asym = 0;
       char asym_id[500], line[200], symmetry[20];
       FILE *fp = NULL;

       memset(asym_id, 0, 500);
       memset(symmetry, 0, 20);
       fp = fopen(support_file, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", support_file);
            return;
       }

       while (!feof(fp)) {
            fgets(line, 199, fp);
            if (feof(fp)) break;
            ndb_clean_string(line);
            if (!strcmp(line, "")) continue;

            if (!strncmp(line, "ASYMID:", 7)) {
                 strcpy(asym_id, &line[7]);
                 flag_asym = 1;
            } else if (!strncmp(line, "SYMMETRY:", 9))
                 strcpy(symmetry, &line[9]);
            else if (!strncmp(line, "END", 3))
                 flag_asym = 0;
            else if (flag_asym) {
                 strcat(asym_id, " ");
                 strcat(asym_id, line);
            }
       }
       fclose (fp);

       ndb_clean_string(asym_id);
       ndb_clean_string(symmetry);
       if (!strcmp(asym_id, "") || !strcmp(symmetry, "")) return;

       op = atoi(symmetry) - 1;
       for (i = 0; i < strlen(symmetry); i++)
            if (symmetry[i] == '_') break;
       lx = symmetry[i + 1] - '5';
       ly = symmetry[i + 2] - '5';
       lz = symmetry[i + 3] - '5';

       _molecules[0]->change_coordinates(asym_id, _cell, op, lx, ly, lz);
}

void _MAXIT::change_coordinates_non_symm(const char *support_file)
{
       int flag_asym = 0, flag_matx = 0, i = 0;
       char asym_id[500], line[200], buf0[20], buf1[20], buf2[20], buf3[20];
       double m[3][4];
       FILE *fp = NULL;

       memset(asym_id, 0, 500);
       m[0][0] = m[1][1] = m[2][2] = 1.0;
       m[0][1] = m[0][2] = m[0][3] = 0.0;
       m[1][0] = m[1][2] = m[1][3] = 0.0;
       m[2][0] = m[2][1] = m[2][3] = 0.0;

       fp = fopen(support_file, "r");
       if (fp == (FILE *) NULL) {
            ndb_log_message(NDB_MSG_ERR, "Can not read file %s!\n", support_file);
            return;
       }
       while (!feof(fp)) {
            fgets(line, 199, fp);
            if (feof(fp)) break;
            ndb_clean_string(line);
            if (!strcmp(line, "")) continue;

            if (!strncmp(line, "ASYMID:", 7)) {
                 strcpy(asym_id, &line[7]);
                 flag_asym = 1;
            } else if (!strncmp(line, "MATRIX:", 7))
                 flag_matx = 1;
            else if (!strncmp(line, "END", 3)) {
                 if (flag_asym) flag_asym = 0;
                 if (flag_matx) flag_matx = 0;
            } else if (flag_asym) {
                 strcat(asym_id, " ");
                 strcat(asym_id, line);
            } else if (flag_matx) {
                 if (i < 3) {
                      sscanf(line, "%s %s %s %s", buf0, buf1, buf2, buf3);
                      m[i][0] = atof(buf0);
                      m[i][1] = atof(buf1);
                      m[i][2] = atof(buf2);
                      m[i][3] = atof(buf3);
                      i++;
                 }
            }
       }
       fclose (fp);

       ndb_clean_string(asym_id);
       if (!strcmp(asym_id, "")) return;

       _molecules[0]->change_coordinates(asym_id, m);
}

void _MAXIT::remove_secondary_structures()
{
       int i;
       _exist_helix = _exist_sheet = _exist_ssbond = 0;

       _CardInfo[HELIX_TOKEN-1].clear_Cards();
       _CardInfo[SHEET_TOKEN-1].clear_Cards();
       _CardInfo[SSBOND_TOKEN-1].clear_Cards();

       Clear_Structural_Feature();
       _alloc_sheet = 0; _n_sheet = 0; _sheet = NULL;
       _alloc_ssbond = 0; _n_ssbond = 0; _ssbond = NULL;
       _alloc_hydbnd = 0; _n_hydbnd = 0; _hydbnd = NULL;
       _alloc_sltbrg = 0; _n_sltbrg = 0; _sltbrg = NULL;
       _alloc_site = 0; _n_site = 0; _site = NULL;
       _alloc_het = 0; _n_het = 0; _het = NULL;
       _alloc_modifb = 0; _n_modifb = 0; _modifb = NULL;
       _alloc_modifp = 0; _n_modifp = 0; _modifp = NULL;
       _alloc_modifs = 0; _n_modifs = 0; _modifs = NULL;
       _alloc_modres = 0; _n_modres = 0; _modres = NULL;
       if (_link) {
            for (i = 0; i < _n_link; i++) {
                 if (_link[i]) {
                      if (_link[i]->details) delete _link[i]->details;
                      delete _link[i];
                 }
            }
            delete [] _link;
       }
       if (_mismat) {
            for (i = 0; i < _n_mismat; i++)
                 if (_mismat[i]) delete _mismat[i];
            delete [] _mismat;
       }
       if (_bspair) {
            for (i = 0; i < _n_bspair; i++)
                 if (_bspair[i]) delete _bspair[i];
            delete [] _bspair;
       }
       _alloc_link = 0; _n_link = 0; _link = NULL;
       _alloc_mismat = 0; _n_mismat = 0; _mismat = NULL;
       _alloc_bspair = 0; _n_bspair = 0; _bspair = NULL;
       
       if (_num_mol == 0 || _molecules == NULL) return;
       _CHAIN *chain = _molecules[0]->GetFirstChain();
       while (chain) {
            if (chain->chain_type() == ATOMP_TOKEN)
                 chain->remove_helix();
            chain = _molecules[0]->GetNextChain();
       }
       if (_CifObj) _CifObj->DeleteTable(_StructureId, "refine_hist");
       delete_atom_count();

       One_Card_Info_Format *pCard = _CardInfo[MISRES_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[MISRES_TOKEN-1].delete_a_card(pCard);
}

void _MAXIT::convert_between_fractional_and_orthogonal(const int iflag)
{
       get_cell();

       ISTable *Table = _CifObj->GetTablePtr(_StructureId, "atom_site");
       if (is_empty_table(Table)) return;

       int x_index = Table->GetColumnIndex("Cartn_x");
       int y_index = Table->GetColumnIndex("Cartn_y");
       int z_index = Table->GetColumnIndex("Cartn_z");

       int x_esd_index = Table->GetColumnIndex("Cartn_x_esd");
       int y_esd_index = Table->GetColumnIndex("Cartn_y_esd");
       int z_esd_index = Table->GetColumnIndex("Cartn_z_esd");

       int rowNo = Table->GetNumRows();
 
       char value[15]; CifString cifstring;
       double x, y, z;
       for (int irow = 0; irow < rowNo; irow++) {
            if (x_index >= 0 && y_index >= 0 && z_index >= 0) {
                 get_value(cifstring, Table, x_index, irow);
                 if (cifstring != "") {
                      x = atof(cifstring.Text());
                      get_value(cifstring, Table, y_index, irow);
                      if (cifstring != "") {
                           y = atof(cifstring.Text());
                           get_value(cifstring, Table, z_index, irow);
                           if (cifstring != "") {
                                z = atof(cifstring.Text());
                                ndb_trans_coord_3by3(&x, &y, &z, _cell, iflag);
                                sprintf(value, "%.3f", x);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, x_index, irow);
                                sprintf(value, "%.3f", y);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, y_index, irow);
                                sprintf(value, "%.3f", z);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, z_index, irow);
                           }
                      }
                 }
            }
            if (x_esd_index >= 0 && y_esd_index >= 0 && z_esd_index >= 0) {
                 get_value(cifstring, Table, x_esd_index, irow);
                 if (cifstring != "") {
                      x = atof(cifstring.Text());
                      get_value(cifstring, Table, y_esd_index, irow);
                      if (cifstring != "") {
                           y = atof(cifstring.Text());
                           get_value(cifstring, Table, z_esd_index, irow);
                           if (cifstring != "") {
                                z = atof(cifstring.Text());
                                ndb_trans_coord_3by3(&x, &y, &z, _cell, iflag);
                                sprintf(value, "%.3f", x);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, x_esd_index, irow);
                                sprintf(value, "%.3f", y);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, y_esd_index, irow);
                                sprintf(value, "%.3f", z);
                                ndb_clean_string(value);
                                cifstring.Copy(value);
                                Table->UpdateCell(cifstring, z_esd_index, irow);
                           }
                      }
                 }
            }
       }
       _CifObj->WriteTable(Table, _StructureId, "atom_site");
}
/*
void _MAXIT::match_struct_asym()
{
       int i, rowNo, id, ndb_pdb_id, entity_id;
       CifString string;
       ISTable *Table = NULL;
       One_Card_Info_Format *pCard = NULL;

       pCard = _CardInfo[SEQIFO_TOKEN-1].Head();
       while (pCard) {
            for (i = 1; i < pCard->NumField(); i++)
                 printf("-%s- ", pCard->Field(i));
            printf("\n");
            pCard = pCard->Next();
       }
       Table = _CifObj->GetTablePtr(_StructureId, "struct_asym");
       rowNo = Table->GetNumRows();
       id = Table->GetColumnIndex("id");
       ndb_pdb_id = Table->GetColumnIndex("ndb_pdb_id");
       entity_id = Table->GetColumnIndex("entity_id");
       for (i = 0; i < rowNo; i++) {
            Table->GetCell(string, id, i);
            printf("-%s- ", string.Text());
            Table->GetCell(string, ndb_pdb_id, i);
            printf("-%s- ", string.Text());
            Table->GetCell(string, entity_id, i);
            printf("-%s-\n", string.Text());
       }
}
*/
#define MAX_LENGTH 60

void _MAXIT::get_one_letter_code_from_coordinates()
{
       int j = 0, len = 0, len1 = 0;
       char *code = NULL;
       _CHAIN *chain = NULL;
       CifString sequence;
       _FIELD *SeqRes = NULL;
       FILE *fp = NULL;

       if (_num_mol == 0 || _molecules == NULL) return;

       fp = fopen(_output_filename, "w");
       chain = _molecules[0]->GetFirstChain();
       while (chain) {
            if (chain->chain_type() == ATOMN_TOKEN ||
                chain->chain_type() == ATOMP_TOKEN) {
                 sequence.Copy("");
                 len = 0;
                 for (j = 0; j < chain->SeqLen(); j++) {
                      SeqRes = chain->SeqRes(j);
                      if (SeqRes->Deleted) continue;
                      code = get_oneletter_code(SeqRes->Field[0]);
                      len1 = strlen(code);
                      if (len1 == 1) {
                           if (len + len1 > MAX_LENGTH) {
                                sequence += "\n";
                                len = 0;
                           }
                           sequence += code;
                           len += len1;
                      } else if (len1 == 2 && code[0] == '+') {
                           if (len + 1 > MAX_LENGTH) {
                                sequence += "\n";
                                len = 0;
                           }
                           sequence += &code[1];
                           len += 1;
                      } else {
                           if (len + len1 + 2 > MAX_LENGTH) {
                                sequence += "\n";
                                len = 0;
                           }
                           sequence += "(";
                           sequence += code;
                           sequence += ")";
                           len += (len1 + 2);
                      }
                 }
                 fprintf(fp, "CHAIN: %s\n", chain->PDB_ChainID());
                 fprintf(fp, "%s\n", sequence.Text());
            }
            chain = _molecules[0]->GetNextChain();
       }
       fclose (fp);
}

void _MAXIT::check_cryst1_card()
{
       if (!_CardInfo[CRYST1_TOKEN-1].Head()) return;

       if (_cell) {
            if (_cell->symops) delete [] _cell->symops;
            delete _cell;
            _cell = NULL;
       }
       if (_CifObj) {
            _CifObj->DeleteTable(_StructureId, "symmetry");
            _CifObj->DeleteTable(_StructureId, "cell");
            _CifObj->DeleteTable(_StructureId, "atom_sites");
            One_Card_Info_Format *pCard = _CardInfo[SCALE_TOKEN-1].Head();
            while (pCard) pCard = _CardInfo[SCALE_TOKEN-1].delete_a_card(pCard);

            CifString string;
            ISTable *Table = new ISTable("cell");
            Table->AddColumn("entry_id");
            Table->AddColumn("length_a");
            Table->AddColumn("length_b");
            Table->AddColumn("length_c");
            Table->AddColumn("angle_alpha");
            Table->AddColumn("angle_beta");
            Table->AddColumn("angle_gamma");
            Table->AddColumn("Z_PDB");
            Table->AddColumn("ndb_unique_axis");
            Table->AddRow();
            string.Copy(_StructureId);
            Table->UpdateCell(string, 0, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(1));
            Table->UpdateCell(string, 1, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(2));
            Table->UpdateCell(string, 2, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(3));
            Table->UpdateCell(string, 3, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(4));
            Table->UpdateCell(string, 4, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(5));
            Table->UpdateCell(string, 5, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(6));
            Table->UpdateCell(string, 6, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(8));
            Table->UpdateCell(string, 7, 0);
            _CifObj->WriteTable(Table, _StructureId, "cell");

            Table = new ISTable("symmetry");
            Table->AddColumn("entry_id");
            Table->AddColumn("space_group_name_H-M");
            Table->AddColumn("ndb_full_space_group_name_H-M");
            Table->AddColumn("cell_setting");
            Table->AddColumn("Int_Tables_number");
            Table->AddRow();
            string.Copy(_StructureId);
            Table->UpdateCell(string, 0, 0);
            string.Copy(_CardInfo[CRYST1_TOKEN-1].Head()->Field(7));
            Table->UpdateCell(string, 1, 0);
            _CifObj->WriteTable(Table, _StructureId, "symmetry");
       }
       get_cell();
}

void _MAXIT::get_biol_unit_formation()
{
       int i, j, k;
       _CHAIN *chain = NULL;
       _STBIOL **stbiol = NULL;

       if (!_n_stbiol || !_stbiol) return;

       _biol_unit_info = new _BIOL_UNIT_INFO*[_n_stbiol];
       for (i = 0; i < _n_stbiol; i++) _biol_unit_info[i] = NULL;

       _n_biol_unit_info = 0;
       for (i = 0; i < _n_stbiol; i++) {
            if (!strcmp(_stbiol[i]->Symmetry, "1_555")) {
                 chain = _molecules[_rep_mol]->GetFirstChain();
                 while (chain) {
                      if (_stbiol[i]->Asym_ID == chain->ChainID()) break;
                      chain = _molecules[_rep_mol]->GetNextChain();
                 }
                 if (!chain) {
                      ndb_log_message(NDB_MSG_ERR, "Can not find asymmetric chain %s\n",
                            _stbiol[i]->Asym_ID.Text());
                      continue;
                 }
                 j = _n_biol_unit_info;
                 _n_biol_unit_info++;
                 _biol_unit_info[j] = new _BIOL_UNIT_INFO;
                 _biol_unit_info[j]->n_stbiol = 1;
                 _biol_unit_info[j]->stbiol = new _STBIOL*[_biol_unit_info[j]->n_stbiol];
                 _biol_unit_info[j]->stbiol[0] = new _STBIOL;
                 *(_biol_unit_info[j]->stbiol[0]) = *(_stbiol[i]);
                 _biol_unit_info[j]->Asym_ID.Copy(_stbiol[i]->Asym_ID);
                 strcpy(_biol_unit_info[j]->PDB_Strand_ID, chain->PDB_ChainID());
                 _biol_unit_info[j]->chain_type = chain->chain_type();
                 strcpy(_biol_unit_info[j]->First_Residue_Name, chain->GetFirstResidue()->ResName());
                 _biol_unit_info[j]->First_Residue_Number = chain->GetFirstResidue()->pdb_res_no();
            } else {
                 for (j = 0; j < _n_biol_unit_info; j++) {
                      if (_biol_unit_info[j]->Asym_ID == _stbiol[i]->Asym_ID) break;
                 }
                 if (j == _n_biol_unit_info) {
                      ndb_log_message(NDB_MSG_ERR, "Can not find asymmetric chain for %s (%s)\n",
                               _stbiol[i]->Asym_ID.Text(), _stbiol[i]->Symmetry);
                      continue;
                 }
                 stbiol = _biol_unit_info[j]->stbiol;
                 _biol_unit_info[j]->n_stbiol++;
                 _biol_unit_info[j]->stbiol = new _STBIOL*[_biol_unit_info[j]->n_stbiol];
                 for (k = 0; k < _biol_unit_info[j]->n_stbiol - 1; k++)
                      _biol_unit_info[j]->stbiol[k] = stbiol[k];
                 delete [] stbiol;
                 _biol_unit_info[j]->stbiol[k] = new _STBIOL;
                 *(_biol_unit_info[j]->stbiol[k]) = *(_stbiol[i]);
            }
       }
       if (!_n_biol_unit_info) {
            delete [] _biol_unit_info;
            _biol_unit_info = NULL;
       }
}

void _MAXIT::put_biol_unit_formation()
{
       int i, j, k, l, n_stbiol;
       _CHAIN *chain = NULL;
       _STBIOL **stbiol = NULL;

       if (!_biol_unit_info || !_n_biol_unit_info) return;

       if (_stbiol) {
            for (i = 0; i < _n_stbiol; i++) if (_stbiol[i]) delete _stbiol[i];
            delete [] _stbiol;
       }
       _stbiol = NULL; _n_stbiol = 0;

       match_stbiol_with_molecules();

       n_stbiol = _n_stbiol;
       for (i = 0; i < n_stbiol; i++) {
            if (!strcmp(_stbiol[i]->Symmetry, "1_555")) {
                 chain = _molecules[_rep_mol]->GetFirstChain();
                 while (chain) {
                      if (_stbiol[i]->Asym_ID == chain->ChainID()) {
                           for (j = 0; j < _n_biol_unit_info; j++) {
                                if (!strcmp(_biol_unit_info[j]->PDB_Strand_ID, chain->PDB_ChainID()) &&
                                    !strcmp(_biol_unit_info[j]->First_Residue_Name, chain->GetFirstResidue()->ResName()) &&
                                    _biol_unit_info[j]->First_Residue_Number == chain->GetFirstResidue()->pdb_res_no() && 
                                    _biol_unit_info[j]->chain_type == chain->chain_type()) {
                                     for (k = 0; k < _biol_unit_info[j]->n_stbiol; k++) {
                                          if (!strcmp(_biol_unit_info[j]->stbiol[k]->Symmetry, "1_555")) {
                                               _stbiol[i]->Biol_ID = _biol_unit_info[j]->stbiol[k]->Biol_ID;
                                               _stbiol[i]->order = _biol_unit_info[j]->stbiol[k]->order;
                                               strcpy(_stbiol[i]->PDB_Strand_ID_Flag,
                                                       _biol_unit_info[j]->stbiol[k]->PDB_Strand_ID_Flag);
                                          } else {
                                               stbiol = _stbiol;
                                               _stbiol = new _STBIOL*[_n_stbiol + 1];
                                               for (l = 0; l < _n_stbiol; l++) _stbiol[l] = stbiol[l];
                                               delete [] stbiol;
                                               _n_stbiol++;
                                               _stbiol[l] = new _STBIOL;
                                               _stbiol[l]->Biol_ID = _biol_unit_info[j]->stbiol[k]->Biol_ID;
                                               _stbiol[l]->order = _biol_unit_info[j]->stbiol[k]->order;
                                               _stbiol[l]->Asym_ID.Copy(_stbiol[i]->Asym_ID);
                                               _stbiol[l]->NDB_Strand_ID.Copy(_stbiol[i]->NDB_Strand_ID);
                                               strcpy(_stbiol[l]->PDB_Strand_ID,
                                                      _biol_unit_info[j]->stbiol[k]->PDB_Strand_ID);
                                               strcpy(_stbiol[l]->PDB_Strand_ID_Flag,
                                                      _biol_unit_info[j]->stbiol[k]->PDB_Strand_ID_Flag);
                                               strcpy(_stbiol[l]->Symmetry,
                                                      _biol_unit_info[j]->stbiol[k]->Symmetry);
                                          }
                                     }
                                     break;
                                }
                           }
                           break;
                      }
                      chain = _molecules[_rep_mol]->GetNextChain();
                 }
            }
       }
}
