/**********************************************
	 *   determine the new Secondary Structure and
	 *   replace the old one with the new one
	 **********************************************/
	Processor::Result SecondaryStructureProcessor::operator() (Composite &composite)
	{
		if (!RTTI::isKindOf<Chain>(composite))
		{
			return Processor::CONTINUE;
		}

		Chain* p = RTTI::castTo<Chain>(composite);
		HBondProcessor hbp;

		p->apply(hbp);       // find all posible HBonds
		
		HBonds_ = hbp.getBackboneHBondPattern();
		ResidueIterator ri = p->beginResidue();
		 
		if (!(+ri))
		{
			return Processor::CONTINUE;
		}
		
		// locate the Secondary Structures
		compute_();

		//----------associate new Secondary Structures (SS) for each residue -----
	  // - summarize equal residues in one new SS (new_ss)
		// - push for each residue the new SS into new_parent  
		// - push all residues into residues
		
		SecondaryStructure* ss = 0;
		char     last_struct   = 'X';
		Position resnum        = 0;
 
		vector<SecondaryStructure*> new_ss;
		vector<SecondaryStructure*> new_parent;
		vector<Residue*> 						residues;

		if (summary_.size() == 0)
			return Processor::CONTINUE;
		
		for (; +ri; ++ri)
		{
			if (resnum >= summary_.size())
			{
				Log.error() << "A problem occured in " << __FILE__ << " " << __LINE__ << std::endl;
				return Processor::CONTINUE;
			}

			// depending on the last type of secondary structure we have seen,
			// we need to react differently to merge them sensibly
			if (last_struct != summary_[resnum])
			{
				switch (last_struct)
				{
					case 'L': // we are in a loop
						// note that we identify 'real' loops, isolated bridges and turns (-,B,T)
						// and map them all to loops. Thus we need to determine here if the current
						// residue also maps to a loop (we already know that the last residue was one)
						switch (summary_[resnum])
						{
							case '-':
							case 'B':
							case 'T': break; // nothing to see here... please walk on...

							default:
								// the current residue is no loop => build a new SecondaryStructure
								ss = new SecondaryStructure;
								last_struct = setSecondaryStructureType_(ss, summary_[resnum]);
								new_ss.push_back(ss);
						}
						break;
				
					default: // in all other cases, setSecondaryStructure does the hard work
						ss = new SecondaryStructure;
						last_struct = setSecondaryStructureType_(ss, summary_[resnum]);
						new_ss.push_back(ss);
				}
			}

			// in all cases, ss is now the new parent of this residue
			new_parent.push_back(ss);
			residues.push_back(&*ri);
			
			resnum++;
		}
		
		// ------ insert Residues to new SS ---------------
		for (Position i = 0; i < residues.size(); i++)
		{
			new_parent[i]->insert(*residues[i]);
		}
	
		// ------ remove old SecondaryStructures ----------
		// we have to be sure not to delete a SS which has an SS as parent!
		// because it would be deleted twice
		vector<SecondaryStructure*> to_remove;
		SecondaryStructureIterator ssit = p->beginSecondaryStructure();
		for (; +ssit; ++ssit)
		{
			if ((*ssit).getParent() == 0 ||
					!RTTI::isKindOf<SecondaryStructure>(*(*ssit).getParent()))
			{
				to_remove.push_back(&*ssit);
			}
		}


		for (Position i = 0; i < to_remove.size(); i++)
		{
			delete to_remove[i];
		}

		BALL_POSTCONDITION_EXCEPTION(p->countSecondaryStructures() == 0, 
		 "SecondaryStructureProcessor did not remove all old secondary structures!")
		
		// ------ insert new SecondaryStructures ----------
		for (Position i = 0; i < new_ss.size(); i++)
		{
			p->insert(*new_ss[i]);
		}
	
		BALL_POSTCONDITION_EXCEPTION(p->countSecondaryStructures() == new_ss.size(),
		 "SecondaryStructureProcessor did not add all new secondary structures!")

		return Processor::CONTINUE;
	}