/* translation of file "util.k" */
/* generated by:
 *  @(#)$Author$
 */
#define KC_FUNCTIONS_util_

#include <stdlib.h>
#include "k.h"
#include "util.h"
namespace kc { }
using namespace kc;
/* included stuff */
//
// The Termprocessor Kimwitu++
//
// Copyright (C) 1991 University of Twente, Dept TIOS.
// Copyright (C) 1998-2003 Humboldt-University of Berlin, Institute of Informatics
// All rights reserved.
//
// Kimwitu++ is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Kimwitu++ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kimwitu++; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

static char util_kAccesSid[] = "@(#)$Id$";

addedphylumdeclarations pl_addedphylumdeclarations = 0;

countedphylumdeclarations pl_countedphylumdeclarations = 0;

#include <string.h>	/* for strcmp */

#include "parse.h"	/* for f_lookupdecl */

static unparseitems** string_collection;
static unparseitems The_Nilunparseitems;
unparseitems The_current_unparseitems;

/* end included stuff */


namespace kc {

#ifndef KC_TRACE_PROVIDED
#define KC_TRACE_PROVIDED(COND,FILE,LINE,NODE) COND
#endif

static  ID f_do_check_unpattributes_in_phylum (unpattributes a, ID p);
static  void v_do_check_dollarvar_in_operators (INT i, operators o, ID p);
static  ID f_do_subphylum (arguments a, INT i, int a_i);
static  argument f_do_argument (arguments a, INT i, int a_i);
static  alternative f_do_alternative (alternatives a, int i, int a_i);
static  storageclasses do_add_to_storageclasses (ID v, ID p, storageclasses s, storageclasses all);
bool f_added(ID id)
{
    {
	ID kc_selvar_0_1 = phylum_cast<ID>( id );
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    return AddedPhylumdeclaration( uid )->added;

	} else
	{ kc_no_default_in_with( "f_added", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

void v_add(ID id)
{
    {
	ID kc_selvar_0_1 = phylum_cast<ID>( id );
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    AddedPhylumdeclaration( uid )->added = true;

	} else
	    kc_no_default_in_with( "v_add", __LINE__, __FILE__ );
    }

}

void v_freeadded()
{
    pl_addedphylumdeclarations->free( true );
    pl_addedphylumdeclarations = 0;

}

int f_getcount(ID id)
{
    {
	ID kc_selvar_0_1 = phylum_cast<ID>( id );
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;
	    return ++(CountedPhylumdeclaration( uid ) -> count); 
	    	} else
	{
	    return 0; /* NOTREACHED */ 
	}
    }

}

void v_resetcount()
{
    if (pl_countedphylumdeclarations) {
	{
	    countedphylumdeclarations kc_fe_selvar_1 =  pl_countedphylumdeclarations ;

	    while(
		    kc_fe_selvar_1->prod_sel() == sel_Conscountedphylumdeclarations
		) {
		countedphylumdeclaration kc_selvar_0_1 = kc_fe_selvar_1->countedphylumdeclaration_1;
		{
		    {
			{
			    const countedphylumdeclaration c = kc_selvar_0_1;

			    c->count = 0;

			}
		    }

		}
		kc_fe_selvar_1 = kc_fe_selvar_1->countedphylumdeclarations_1;

	    }
	}
    }   
}

void v_freecount()
{
    if (pl_countedphylumdeclarations) {
	v_resetcount();
	pl_countedphylumdeclarations->free( true );
	pl_countedphylumdeclarations = 0;
    }   
}

bool is_uview_var(ID id)
{
    if(!The_current_unparseitems)
    return false;
    {
	unparseitems kc_fe_selvar_1 =  The_current_unparseitems;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consunparseitems
	    ) {
	    unparseitem kc_selvar_0_1 = kc_fe_selvar_1->unparseitem_1;
	    {
		{
		    {
			const unparseitem item = kc_selvar_0_1;
			{
			    unparseitem kc_selvar_1_1 = phylum_cast<unparseitem>(item);
			    if ((kc_selvar_1_1->prod_sel() == sel_UViewVarDecl)) {
				const ID var = phylum_cast<const impl_unparseitem_UViewVarDecl*>(kc_selvar_1_1)->ID_2;

				if(var->eq(id)) {
				    id->type=ITUViewVar();
				    return true;
				}

			    } else
			    {

			    }
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->unparseitems_1;

	}
    }
    return false;

}

bool f_DvIsDisallowed(dollarvarstatus dvs)
{{
	dollarvarstatus kc_selvar_0_1 = phylum_cast<dollarvarstatus>(dvs);
	if ((kc_selvar_0_1->prod_sel() == sel_DVDisallowed)) {
	    return true; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_DVAllowed)) {
	    return false; 
	    	} else
	{ kc_no_default_in_with( "f_DvIsDisallowed", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

ID f_listelementphylum(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    const phylumdeclaration pd = phylum_cast<const impl_IDtype_ITUserPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;

		    {
			phylumdeclaration kc_selvar_2_1 = phylum_cast<phylumdeclaration>( pd );
			if ((kc_selvar_2_1->prod_sel() == sel_PhylumDeclaration) && (phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1->prod_sel() == sel_ListAlternatives)) {
			    const ID i = phylum_cast<const impl_productionblock_ListAlternatives*>(phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1)->ID_1;

			    return i;

			} else
			{
			    return f_emptyId(); 
			}
		    }

		} else
		{
		    return f_emptyId(); 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_listelementphylum", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_listelementconsoperator(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    const phylumdeclaration pd = phylum_cast<const impl_IDtype_ITUserPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;

		    {
			phylumdeclaration kc_selvar_2_1 = phylum_cast<phylumdeclaration>( pd );
			if ((kc_selvar_2_1->prod_sel() == sel_PhylumDeclaration) && (phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1->prod_sel() == sel_ListAlternatives) && (phylum_cast<const impl_productionblock_ListAlternatives*>(phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1)->alternatives_1->prod_sel() == sel_Consalternatives) && ((phylum_cast<const impl_productionblock_ListAlternatives*>(phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1)->alternatives_1)->alternative_1->prod_sel() == sel_Alternative)) {
			    const ID Cons_id = phylum_cast<const impl_alternative_Alternative*>((phylum_cast<const impl_productionblock_ListAlternatives*>(phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_2_1)->productionblock_1)->alternatives_1)->alternative_1)->ID_1;

			    return Cons_id;

			} else
			{
			    return f_emptyId(); 
			}
		    }

		} else
		{
		    return f_emptyId(); 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_listelementconsoperator", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_emptyId()
{
    static ID emptyID = 0;
    if (! emptyID) {
	emptyID = Id (Str( mkcasestring( "" )));
    }
    return emptyID;

}

bool f_operatorinphylum(ID oid, ID pid)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(oid);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator)) {
		    const ID id = phylum_cast<const impl_IDtype_ITUserOperator*>(kc_selvar_1_1)->ID_1;
		    return pid->eq( id ); 
		    	} else
		{
		    return false; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_operatorinphylum", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

bool f_isphylum(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    return true; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedPhylum)) {
		    return true; 
		    	} else
		{
		    return false; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_isphylum", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

phylumdeclaration f_phylumdeclofid(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    const phylumdeclaration dcl = phylum_cast<const impl_IDtype_ITUserPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;
		    return dcl; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedPhylum)) {
		    const phylumdeclaration dcl = phylum_cast<const impl_IDtype_ITPredefinedPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;
		    return dcl; 
		    	} else
		{
		    return NULL; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_phylumdeclofid", __LINE__, __FILE__ );
	    return static_cast<phylumdeclaration>(0); }
    }

}

bool f_ispredefinedphylum(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedPhylum)) {
		    return true; 
		    	} else
		{
		    return false; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_ispredefinedphylum", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

alternative f_alternativeofoperator(ID oid)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(oid);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator)) {
		    const alternative a = phylum_cast<const impl_IDtype_ITUserOperator*>(kc_selvar_1_1)->alternative_1;
		    return a; 
		    	} else
		{
		    return 0; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_alternativeofoperator", __LINE__, __FILE__ );
	    return static_cast<alternative>(0); }
    }

}

arguments f_argumentsofoperator(ID oid)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(oid);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator) && (phylum_cast<const impl_IDtype_ITUserOperator*>(kc_selvar_1_1)->alternative_1->prod_sel() == sel_Alternative)) {
		    const arguments args = phylum_cast<const impl_alternative_Alternative*>(phylum_cast<const impl_IDtype_ITUserOperator*>(kc_selvar_1_1)->alternative_1)->arguments_1;
		    return args; 
		    	} else
		{
		    return Nilarguments(); 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_argumentsofoperator", __LINE__, __FILE__ );
	    return static_cast<arguments>(0); }
    }

}

ID f_phylumofoperator(ID oid)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(oid);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator)) {
		    const ID id = phylum_cast<const impl_IDtype_ITUserOperator*>(kc_selvar_1_1)->ID_1;
		    return id; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedOperator)) {
		    const ID id = phylum_cast<const impl_IDtype_ITPredefinedOperator*>(kc_selvar_1_1)->ID_1;
		    return id; 
		    	} else
		{
		    return f_emptyId(); 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_phylumofoperator", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_phylumofpatternID(ID vid)
{
    {
	IDtype kc_selvar_0_1 = phylum_cast<IDtype>( vid->type );
	if ((kc_selvar_0_1->prod_sel() == sel_ITPatternVariable)) {
	    const ID id = phylum_cast<const impl_IDtype_ITPatternVariable*>(kc_selvar_0_1)->ID_1;
	    return id; 
	    	} else
	{
	    return f_emptyId(); 
	}
    }

}

ID f_phylumofpatternvariable(ID vid)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(vid);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITPatternVariable)) {
		    const ID id = phylum_cast<const impl_IDtype_ITPatternVariable*>(kc_selvar_1_1)->ID_1;
		    return id; 
		    	} else
		{
		    return f_emptyId(); 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_phylumofpatternvariable", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

void v_syn_type_attribute_ID(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITPatternVariable)) {
		    id->type = uid->type; 
		    	} else
		{
		    /* EMPTY */
		}
	    }

	} else
	    kc_no_default_in_with( "v_syn_type_attribute_ID", __LINE__, __FILE__ );
    }

}

bool f_Nilarguments(arguments a)
{{
	arguments kc_selvar_0_1 = phylum_cast<arguments>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consarguments)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilarguments)) {
	    return true; 
	    	} else
	{ kc_no_default_in_with( "f_Nilarguments", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

ID f_hd_arguments(arguments a)
{{
	arguments kc_selvar_0_1 = phylum_cast<arguments>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consarguments)) {
	    const ID hd = (kc_selvar_0_1)->ID_1;
	    return hd; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilarguments)) {

	    assertionFailed("Head of empty argument list requested");
	    return 0;

	} else
	{ kc_no_default_in_with( "f_hd_arguments", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

arguments f_tl_arguments(arguments a)
{{
	arguments kc_selvar_0_1 = phylum_cast<arguments>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consarguments)) {
	    const arguments tl = (kc_selvar_0_1)->arguments_1;
	    return tl; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilarguments)) {

	    assertionFailed("Tail of empty argument list requested");
	    return 0;

	} else
	{ kc_no_default_in_with( "f_tl_arguments", __LINE__, __FILE__ );
	    return static_cast<arguments>(0); }
    }

}

void v_check_dollarvar_attribute_in_operators(INT i, unpattributes a, operators o)
{{
	operators kc_selvar_0_1 = phylum_cast<operators>(o);
	if ((kc_selvar_0_1->prod_sel() == sel_Consoperators)) {
	    const ID o_o = (kc_selvar_0_1)->ID_1;
	    const operators o_os = (kc_selvar_0_1)->operators_1;

	    ID phy = f_subphylumofoperator( o_o, i );
	    if (phy->eq(f_emptyId())) {
		v_report(NonFatal( FileLine( i->file, i->line ),
			Problem1S1INT1S1ID( "illegal dollar variable", i,
			    "not that many subterms in operator", o_o )));
	    } else {
		f_check_unpattributes_in_phylum( a, phy );
		v_do_check_dollarvar_in_operators( i, o_os, phy );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Niloperators)) {
	    /* EMPTY */ 
	    	} else
	    kc_no_default_in_with( "v_check_dollarvar_attribute_in_operators", __LINE__, __FILE__ );
    }

}

ID f_check_unpattributes_in_phylum(unpattributes a, ID p)
{
    ID tmp;
    unpattributes t = a->reverse();
    tmp = f_do_check_unpattributes_in_phylum( t, p );
    t->freelist();
    return tmp;

}

static  ID f_do_check_unpattributes_in_phylum(unpattributes a, ID p)
{{
	unpattributes kc_selvar_0_1 = phylum_cast<unpattributes>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consunpattributes)) {
	    const ID a_id = (kc_selvar_0_1)->ID_1;
	    const unpattributes r_a = (kc_selvar_0_1)->unpattributes_1;

	    ID type = f_typeof_attribute_in_phylym( a_id, p );
	    if ( type->eq(f_emptyId() )) {
		v_report(NonFatal( FileLine( a_id->file, a_id->line ),
			Problem1S1ID1S1ID( "attribute", a_id, "not defined in phylum", p )));
		return f_emptyId();
	    } else {
		return f_do_check_unpattributes_in_phylum( r_a, type );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilunpattributes)) {
	    return p; 
	    	} else
	{ kc_no_default_in_with( "f_do_check_unpattributes_in_phylum", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

static  void v_do_check_dollarvar_in_operators(INT i, operators o, ID p)
{{
	operators kc_selvar_0_1 = phylum_cast<operators>(o);
	if ((kc_selvar_0_1->prod_sel() == sel_Consoperators)) {
	    const ID o_o = (kc_selvar_0_1)->ID_1;
	    const operators o_os = (kc_selvar_0_1)->operators_1;

	    ID phy = f_subphylumofoperator( o_o, i );
	    if (phy->eq(f_emptyId())) {
		v_report(NonFatal( FileLine( i->file, i->line ),
			Problem1S1INT1S1ID( "illegal dollar variable", i,
			    "not that many subterms in operator", o_o )));
	    } else if (! p->eq( phy )) {
		v_report(NonFatal( FileLine( i->file, i->line ),
			Problem1S1INT1S1ID1S1ID( " type mismatch for dollar varariable:", i,
			    "; old type", p, "; new type", phy )));
	    }
	    v_do_check_dollarvar_in_operators( i, o_os, p );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Niloperators)) {
	    /* EMPTY */
	    	} else
	    kc_no_default_in_with( "v_do_check_dollarvar_in_operators", __LINE__, __FILE__ );
    }

}

bool f_attribute_in_phylym(ID a, ID p)
{
    return f_typeof_attribute_in_phylym(a, p)->eq(f_emptyId()) ?  false : true;

}

ID f_typeof_attribute_in_phylym(ID a, ID p)
{
    phylumdeclaration tmp = f_lookupdecl( p );
    if ( tmp == 0 ) {
	v_report(NonFatal( FileLine( p->file, p->line ),
		Problem1S1ID( "internal error: could not find declaration of phylum:",
		    p )));
	return f_emptyId();
    }
    {
	phylumdeclaration kc_selvar_0_1 = phylum_cast<phylumdeclaration>( tmp );
	if ((kc_selvar_0_1->prod_sel() == sel_PhylumDeclaration) && (phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->Ccode_option_1->prod_sel() == sel_CcodeOption)) {
	    const attributes attrs = phylum_cast<const impl_Ccode_option_CcodeOption*>(phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->Ccode_option_1)->attributes_1;

	    {
		attributes kc_fe_selvar_1 =  attrs ;

		while(
			kc_fe_selvar_1->prod_sel() == sel_Consattributes
		    ) {
		    attribute kc_selvar_1_1 = kc_fe_selvar_1->attribute_1;
		    {
			{
			    if ((kc_selvar_1_1->prod_sel() == sel_Attribute)) {
				const ID a_type = phylum_cast<const impl_attribute_Attribute*>(kc_selvar_1_1)->ID_1;
				const ID a_id = phylum_cast<const impl_attribute_Attribute*>(kc_selvar_1_1)->ID_2;

				if (a->eq(a_id))
				return a_type;

			    } else
			    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
			}

		    }
		    kc_fe_selvar_1 = kc_fe_selvar_1->attributes_1;

		}
	    }
	    {
		fndeclarations kc_fe_selvar_1 =  kc_selvar_0_1->additional_members;

		while(
			kc_fe_selvar_1->prod_sel() == sel_Consfndeclarations
		    ) {
		    fndeclaration kc_selvar_1_1 = kc_fe_selvar_1->fndeclaration_1;
		    {
			{
			    if ((kc_selvar_1_1->prod_sel() == sel_AcMemberDeclaration) && (phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declaration_specifiers_1->prod_sel() == sel_Consac_declaration_specifiers) && ((phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declaration_specifiers_1)->ac_declaration_specifier_1->prod_sel() == sel_AcDeclSpecTypeSpec) && (phylum_cast<const impl_ac_declaration_specifier_AcDeclSpecTypeSpec*>((phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declaration_specifiers_1)->ac_declaration_specifier_1)->ac_type_specifier_1->prod_sel() == sel_AcTypeSpec) && (phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcMemberDecl)) {
				const ID a_type = phylum_cast<const impl_ac_type_specifier_AcTypeSpec*>(phylum_cast<const impl_ac_declaration_specifier_AcDeclSpecTypeSpec*>((phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declaration_specifiers_1)->ac_declaration_specifier_1)->ac_type_specifier_1)->ID_1;
				const ID a_id = phylum_cast<const impl_ac_direct_declarator_AcMemberDecl*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ID_2;

				if (a->eq(a_id))
				return a_type;

			    } else
			    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
			}

		    }
		    kc_fe_selvar_1 = kc_fe_selvar_1->fndeclarations_1;

		}
	    }
	    return f_emptyId();

	} else
	{ kc_no_default_in_with( "f_typeof_attribute_in_phylym", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_subphylumofoperator(ID o, INT i)
{{
	INT kc_selvar_0_1 = phylum_cast<INT>(i);
	if ((kc_selvar_0_1->prod_sel() == sel_Int)) {
	    const integer ii = phylum_cast<const impl_INT_Int*>(kc_selvar_0_1)->integer_1;

	    if (ii->value == 0) {
		return f_phylumofoperator( o );
	    } else {
		return f_subphylum( f_argumentsofoperator( o ), i );
	    }   
	    	} else
	{ kc_no_default_in_with( "f_subphylumofoperator", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_subphylum(arguments a, INT i)
{
    return f_do_subphylum( a, i, a->length() );

}

static  ID f_do_subphylum(arguments a, INT i, int a_i)
{{
	arguments kc_selvar_0_1 = phylum_cast<arguments>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consarguments)) {
	    const ID a_a = (kc_selvar_0_1)->ID_1;
	    const arguments a_as = (kc_selvar_0_1)->arguments_1;

	    {
		INT kc_selvar_1_1 = phylum_cast<INT>( i );
		if ((kc_selvar_1_1->prod_sel() == sel_Int)) {
		    const integer ii = phylum_cast<const impl_INT_Int*>(kc_selvar_1_1)->integer_1;

		    if (ii->value == a_i) {
			return a_a;
		    } else {
			return f_do_subphylum( a_as, i, a_i - 1 );
		    }   
		    	} else
		{ kc_no_default_in_with( "f_do_subphylum", __LINE__, __FILE__ );
		    return static_cast<ID>(0); }
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilarguments)) {
	    return f_emptyId(); 
	    	} else
	{ kc_no_default_in_with( "f_do_subphylum", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

argument f_argumentofoperator(ID o, INT i)
{{
	INT kc_selvar_0_1 = phylum_cast<INT>(i);
	if ((kc_selvar_0_1->prod_sel() == sel_Int)) {
	    const integer ii = phylum_cast<const impl_INT_Int*>(kc_selvar_0_1)->integer_1;

	    if (ii->value == 0) {
		return Argument( f_phylumofoperator( o ), mkinteger(0));
	    } else {
		return f_argument( f_argumentsofoperator( o ), i );
	    }   
	    	} else
	{ kc_no_default_in_with( "f_argumentofoperator", __LINE__, __FILE__ );
	    return static_cast<argument>(0); }
    }

}

argument f_argument(arguments a, INT i)
{
    return f_do_argument( a, i, a->length() );

}

static  argument f_do_argument(arguments a, INT i, int a_i)
{{
	arguments kc_selvar_0_1 = phylum_cast<arguments>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consarguments)) {
	    const ID a_a = (kc_selvar_0_1)->ID_1;
	    const arguments a_as = (kc_selvar_0_1)->arguments_1;

	    {
		INT kc_selvar_1_1 = phylum_cast<INT>( i );
		if ((kc_selvar_1_1->prod_sel() == sel_Int)) {
		    const integer ii = phylum_cast<const impl_INT_Int*>(kc_selvar_1_1)->integer_1;

		    if (ii->value == a_i) {
			return Argument( a_a, mkinteger(a->seqnr) );
		    } else {
			return f_do_argument( a_as, i, a_i - 1 );
		    }   
		    	} else
		{ kc_no_default_in_with( "f_do_argument", __LINE__, __FILE__ );
		    return static_cast<argument>(0); }
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilarguments)) {
	    return Argument(f_emptyId(), mkinteger(0)); 
	    	} else
	{ kc_no_default_in_with( "f_do_argument", __LINE__, __FILE__ );
	    return static_cast<argument>(0); }
    }

}

ID f_phylumofoutmostpattern(outmostpattern p)
{{
	outmostpattern kc_selvar_0_1 = phylum_cast<outmostpattern>(p);
	if ((kc_selvar_0_1->prod_sel() == sel_OPWildcard)) {
	    return f_emptyId(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPDefault)) {
	    return f_emptyId(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPNonLeafVariable)) {
	    const outmostpattern r_p = phylum_cast<const impl_outmostpattern_OPNonLeafVariable*>(kc_selvar_0_1)->outmostpattern_1;
	    return f_phylumofoutmostpattern( r_p ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPOperator)) {
	    const ID o = phylum_cast<const impl_outmostpattern_OPOperator*>(kc_selvar_0_1)->ID_1;
	    return f_phylumofoperator( o ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPOperatorWildcard)) {
	    const ID o = phylum_cast<const impl_outmostpattern_OPOperatorWildcard*>(kc_selvar_0_1)->ID_1;
	    return f_phylumofoperator( o ); 
	    	} else
	{ kc_no_default_in_with( "f_phylumofoutmostpattern", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_operatorofphylum(ID p, int i)
{
    phylumdeclaration tmp = f_lookupdecl( p );
    if ( tmp == 0 ) {
	v_report(NonFatal( FileLine( p->file, p->line ),
		Problem1S1ID( "internal error: could not find declaration of phylum:",
		    p )));
	return f_emptyId();
    }
    {
	phylumdeclaration kc_selvar_0_1 = phylum_cast<phylumdeclaration>( tmp );
	if ((kc_selvar_0_1->prod_sel() == sel_PhylumDeclaration)) {
	    const productionblock pb = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->productionblock_1;

	    {
		productionblock kc_selvar_1_1 = phylum_cast<productionblock>( pb );
		if ((kc_selvar_1_1->prod_sel() == sel_PredefinedAlternatives)) {
		    const alternatives a = phylum_cast<const impl_productionblock_PredefinedAlternatives*>(kc_selvar_1_1)->alternatives_1;

		    alternative tmp_a = f_alternative( a, i );
		    if ( tmp_a == 0 ) {
			v_report(NonFatal( FileLine( p->file, p->line ),
				Problem1S1ID(
				    "internal error: could not find operators of phylum:",
				    p )));
			return f_emptyId();
		    }
		    {
			alternative kc_selvar_2_1 = phylum_cast<alternative>( tmp_a );
			if ((kc_selvar_2_1->prod_sel() == sel_Alternative)) {
			    const ID id = phylum_cast<const impl_alternative_Alternative*>(kc_selvar_2_1)->ID_1;
			    return id; 
			    	} else
			{ kc_no_default_in_with( "f_operatorofphylum", __LINE__, __FILE__ );
			    return static_cast<ID>(0); }
		    }

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_NonlistAlternatives)) {
		    const alternatives a = phylum_cast<const impl_productionblock_NonlistAlternatives*>(kc_selvar_1_1)->alternatives_1;

		    alternative tmp_a = f_alternative( a, i );
		    if ( tmp_a == 0 ) {
			v_report(NonFatal( FileLine( p->file, p->line ),
				Problem1S1ID(
				    "internal error: could not find operators of phylum:",
				    p )));
			return f_emptyId();
		    }
		    {
			alternative kc_selvar_2_1 = phylum_cast<alternative>( tmp_a );
			if ((kc_selvar_2_1->prod_sel() == sel_Alternative)) {
			    const ID id = phylum_cast<const impl_alternative_Alternative*>(kc_selvar_2_1)->ID_1;
			    return id; 
			    	} else
			{ kc_no_default_in_with( "f_operatorofphylum", __LINE__, __FILE__ );
			    return static_cast<ID>(0); }
		    }

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ListAlternatives)) {
		    const alternatives a = phylum_cast<const impl_productionblock_ListAlternatives*>(kc_selvar_1_1)->alternatives_1;

		    alternative tmp_a = f_alternative( a, i );
		    if ( tmp_a == 0 ) {
			v_report(NonFatal( FileLine( p->file, p->line ),
				Problem1S1ID(
				    "internal error: could not find operators of phylum:",
				    p )));
			return f_emptyId();
		    }
		    {
			alternative kc_selvar_2_1 = phylum_cast<alternative>( tmp_a );
			if ((kc_selvar_2_1->prod_sel() == sel_Alternative)) {
			    const ID id = phylum_cast<const impl_alternative_Alternative*>(kc_selvar_2_1)->ID_1;
			    return id; 
			    	} else
			{ kc_no_default_in_with( "f_operatorofphylum", __LINE__, __FILE__ );
			    return static_cast<ID>(0); }
		    }

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_Emptyproductionblock)) {
		    return f_emptyId(); 
		    	} else
		{ kc_no_default_in_with( "f_operatorofphylum", __LINE__, __FILE__ );
		    return static_cast<ID>(0); }
	    }

	} else
	{ kc_no_default_in_with( "f_operatorofphylum", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

alternative f_alternative(alternatives a, int i)
{
    return f_do_alternative( a, i, a->length() );

}

static  alternative f_do_alternative(alternatives a, int i, int a_i)
{{
	alternatives kc_selvar_0_1 = phylum_cast<alternatives>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consalternatives)) {
	    const alternative a_a = (kc_selvar_0_1)->alternative_1;
	    const alternatives a_as = (kc_selvar_0_1)->alternatives_1;

	    if (i == a_i) {
		return a_a;
	    } else {
		return f_do_alternative( a_as, i, a_i - 1 );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilalternatives)) {
	    return 0; 
	    	} else
	{ kc_no_default_in_with( "f_do_alternative", __LINE__, __FILE__ );
	    return static_cast<alternative>(0); }
    }

}

void v_reset_phylumdeclaration_marks()
{
    {
	phylumdeclarations kc_fe_selvar_1 =  Thephylumdeclarations ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consphylumdeclarations
	    ) {
	    phylumdeclaration kc_selvar_0_1 = kc_fe_selvar_1->phylumdeclaration_1;
	    {
		{
		    {
			const phylumdeclaration p = kc_selvar_0_1;

			p->marked = 0;

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->phylumdeclarations_1;

	}
    }

}

void v_reset_variables_type(variables v)
{
    {
	variables kc_fe_selvar_1 =  v ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consvariables
	    ) {
	    ID kc_selvar_0_1 = kc_fe_selvar_1->ID_1;
	    {
		{
		    {
			const ID var = kc_selvar_0_1;

			{
			    ID kc_selvar_1_1 = phylum_cast<ID>( var );
			    if ((kc_selvar_1_1->prod_sel() == sel_Id)) {
				const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_1_1)->uniqID_1;

				{
				    IDtype kc_selvar_2_1 = phylum_cast<IDtype>( uid->type );
				    if ((kc_selvar_2_1->prod_sel() == sel_ITPatternVariable)) {
					const integer uid_scope = phylum_cast<const impl_IDtype_ITPatternVariable*>(kc_selvar_2_1)->integer_1;

					{
					    scopetypefilelinestack kc_selvar_3_1 = phylum_cast<scopetypefilelinestack>( uid->scopeinfo );
					    if ((kc_selvar_3_1->prod_sel() == sel_Consscopetypefilelinestack) && ((kc_selvar_3_1)->scopetypefileline_1->prod_sel() == sel_ScopeTypeFileLine)) {
						const integer s = phylum_cast<const impl_scopetypefileline_ScopeTypeFileLine*>((kc_selvar_3_1)->scopetypefileline_1)->integer_1;
						const IDtype t = phylum_cast<const impl_scopetypefileline_ScopeTypeFileLine*>((kc_selvar_3_1)->scopetypefileline_1)->IDtype_1;
						const casestring f = phylum_cast<const impl_scopetypefileline_ScopeTypeFileLine*>((kc_selvar_3_1)->scopetypefileline_1)->casestring_1;
						const integer l = phylum_cast<const impl_scopetypefileline_ScopeTypeFileLine*>((kc_selvar_3_1)->scopetypefileline_1)->integer_2;
						const scopetypefilelinestack r_scopeinfo = (kc_selvar_3_1)->scopetypefilelinestack_1;

						if (s == uid_scope) {
						    uid->type = t;
						    uid->file = f;
						    uid->line = l->value;
						    uid->scopeinfo = r_scopeinfo;
						} 
							} else
						if ((kc_selvar_3_1->prod_sel() == sel_Nilscopetypefilelinestack)) {

						uid->type = ITUnknown();
						uid->file = mkcasestring("");
						uid->line = 0;

					    } else
						kc_no_default_in_with( "v_reset_variables_type", __LINE__, __FILE__ );
					}

				    } else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUserRView)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITPredefinedRView)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUserUView)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITPredefinedUView)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUserFunction)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITStorageClass)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITPredefinedStorageClass)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUserOperator)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITPredefinedOperator)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUserPhylum)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITPredefinedPhylum)) {
					/* EMPTY */
						} else
					if ((kc_selvar_2_1->prod_sel() == sel_ITUnknown)) {
					/* EMPTY */
						} else
					kc_no_default_in_with( "v_reset_variables_type", __LINE__, __FILE__ );
				}

			    } else
				kc_no_default_in_with( "v_reset_variables_type", __LINE__, __FILE__ );
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->variables_1;

	}
    }

}

void v_add_to_uviewnames(ID v)
{
    {
	viewnames kc_fe_selvar_1 =  Theuviewnames ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consviewnames
	    ) {
	    ID kc_selvar_0_1 = kc_fe_selvar_1->ID_1;
	    {
		{
		    {
			const ID vn = kc_selvar_0_1;

			if ( vn->eq( v )) return;

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->viewnames_1;

	}
    }
    Theuviewnames = Consviewnames( v, Theuviewnames );

}

void v_add_to_uviewnames_ext(ID v)
{
    viewnames uviewnames=Theuviewnames;
    while(uviewnames) {
	{
	    viewnames kc_selvar_0_1 = phylum_cast<viewnames>(uviewnames);
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilviewnames)) {
		uviewnames=0; 
			} else
		if ((kc_selvar_0_1->prod_sel() == sel_Consviewnames)) {
		const viewnames node = kc_selvar_0_1;
		const ID vn = (kc_selvar_0_1)->ID_1;
		const viewnames tail = (kc_selvar_0_1)->viewnames_1;

		if(vn->eq(v)) {
		    if(!node->is_extern)
		    node->is_extern=true;
		    return;
		}
		uviewnames=tail;

	    } else
		kc_no_default_in_with( "v_add_to_uviewnames_ext", __LINE__, __FILE__ );
	}
    }
    Theuviewnames = Consviewnames( v, Theuviewnames );
    Theuviewnames->is_extern=true;

}

void v_add_to_rviewnames(ID v)
{
    {
	viewnames kc_fe_selvar_1 =  Therviewnames ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consviewnames
	    ) {
	    ID kc_selvar_0_1 = kc_fe_selvar_1->ID_1;
	    {
		{
		    {
			const ID vn = kc_selvar_0_1;

			if ( vn->eq( v )) return;

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->viewnames_1;

	}
    }
    Therviewnames = Consviewnames( v, Therviewnames );

}

void v_add_to_rviewnames_ext(ID v)
{
    viewnames rviewnames=Therviewnames;
    while(rviewnames) {
	{
	    viewnames kc_selvar_0_1 = phylum_cast<viewnames>(rviewnames);
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilviewnames)) {
		rviewnames=0; 
			} else
		if ((kc_selvar_0_1->prod_sel() == sel_Consviewnames)) {
		const viewnames node = kc_selvar_0_1;
		const ID vn = (kc_selvar_0_1)->ID_1;
		const viewnames tail = (kc_selvar_0_1)->viewnames_1;

		if(vn->eq(v)) {
		    if(!node->is_extern)
		    node->is_extern=true;
		    return;
		}
		rviewnames=tail;

	    } else
		kc_no_default_in_with( "v_add_to_rviewnames_ext", __LINE__, __FILE__ );
	}
    }
    Therviewnames = Consviewnames( v, Therviewnames );
    Therviewnames->is_extern=true;

}

void v_add_to_storageclasses(ID v, ID p)
{
    Thestorageclasses =
    do_add_to_storageclasses( v, p, Thestorageclasses, Thestorageclasses );

}

static  storageclasses do_add_to_storageclasses(ID v, ID p, storageclasses s, storageclasses all)
{{
	storageclasses kc_selvar_0_1 = phylum_cast<storageclasses>(s);
	if ((kc_selvar_0_1->prod_sel() == sel_Consstorageclasses)) {
	    const ID sc = (kc_selvar_0_1)->ID_1;
	    const storageclasses r_sc = (kc_selvar_0_1)->storageclasses_1;

	    if ( sc->eq( v )) {
		if (! p->eq(f_emptyId())) {
		    s->phyla = Consphylumnames( p, s->phyla );
		}
		return all;
	    } else {
		return do_add_to_storageclasses( v, p, r_sc, all );
	    }       
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilstorageclasses)) {

	    storageclasses tmp = Consstorageclasses( v, all );
	    tmp->phyla = Nilphylumnames();
	    if (! p->eq(f_emptyId())) {
		tmp->phyla = Consphylumnames( p, tmp->phyla );
	    }
	    return tmp;

	} else
	{ kc_no_default_in_with( "do_add_to_storageclasses", __LINE__, __FILE__ );
	    return static_cast<storageclasses>(0); }
    }

}

void collect_strings()
{
    long i;
    long ssize=last_text_nr()+1;
    int lsize=Thelanguages->length();
    The_Nilunparseitems=Nilunparseitems();
    string_collection=new unparseitems*[ssize];
    for( i=0; i<ssize;i++) {
	int j=0;
	string_collection[i]=new unparseitems[lsize];
	for(;j<lsize;j++)
	string_collection[i][j]=The_Nilunparseitems;
    }
    Theunparsedeclarations->unparse(v_null_printer, view_collect_strings);

}

void add_string_to_collection(unparseitem s)
{{
	unparseitem kc_selvar_0_1 = phylum_cast<unparseitem>(s);
	if ((kc_selvar_0_1->prod_sel() == sel_UnpStr) && (phylum_cast<const impl_unparseitem_UnpStr*>(kc_selvar_0_1)->languageoption_1->prod_sel() == sel_LanguageList)) {
	    const languagenames langs = phylum_cast<const impl_languageoption_LanguageList*>(phylum_cast<const impl_unparseitem_UnpStr*>(kc_selvar_0_1)->languageoption_1)->languagenames_1;

	    long nr=s->text_nr;
	    {
		languagenames kc_fe_selvar_1 =  langs;

		while(
			kc_fe_selvar_1->prod_sel() == sel_Conslanguagenames
		    ) {
		    ID kc_selvar_1_1 = kc_fe_selvar_1->ID_1;
		    {
			{
			    if ((kc_selvar_1_1->prod_sel() == sel_Id)) {
				const uniqID u_id = phylum_cast<const impl_ID_Id*>(kc_selvar_1_1)->uniqID_1;

				{
				    IDtype kc_selvar_2_1 = phylum_cast<IDtype>((IDtype)u_id->type);
				    if ((kc_selvar_2_1->prod_sel() == sel_ITLanguageName)) {
					const integer l = phylum_cast<const impl_IDtype_ITLanguageName*>(kc_selvar_2_1)->integer_1;

					unparseitems entry=string_collection[nr][l->value];
					{
					    unparseitems kc_selvar_3_1 = phylum_cast<unparseitems>(entry);
					    if ((kc_selvar_3_1->prod_sel() == sel_Consunparseitems) && ((kc_selvar_3_1)->unparseitem_1->prod_sel() == sel_UnpStr) && (phylum_cast<const impl_unparseitem_UnpStr*>((kc_selvar_3_1)->unparseitem_1)->languageoption_1->prod_sel() == sel_NoLanguagename) && ((kc_selvar_3_1)->unparseitems_1->prod_sel() == sel_Nilunparseitems)) {

						string_collection[nr][l->value]=Consunparseitems(s,The_Nilunparseitems);

					    } else
						if ((kc_selvar_3_1->prod_sel() == sel_Nilunparseitems)) {

						string_collection[nr][l->value]=Consunparseitems(s,The_Nilunparseitems);

					    } else
					    {

						string_collection[nr][l->value]= Consunparseitems(s,entry);

					    }
					}

				    } else
				    {
					/* EMPTY */ 
				    }
				}

			    } else
			    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
			}

		    }
		    kc_fe_selvar_1 = kc_fe_selvar_1->languagenames_1;

		}
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_UnpStr) && (phylum_cast<const impl_unparseitem_UnpStr*>(kc_selvar_0_1)->languageoption_1->prod_sel() == sel_NoLanguagename)) {

	    int lsize=Thelanguages->length();
	    long nr=s->text_nr;
	    int i;
	    for(i=0;i<lsize;i++) {
		unparseitems entry=string_collection[nr][i];
		string_collection[nr][i]= Consunparseitems(s,entry);
	    }

	} else
	    kc_no_default_in_with( "add_string_to_collection", __LINE__, __FILE__ );
    }

}

void unparse_string_collection()
{
    int l=Thelanguages->length();
    long ssize=last_text_nr()+1;
    {
	languagenames kc_fe_selvar_1 =  Thelanguages;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conslanguagenames
	    ) {
	    ID kc_selvar_0_1 = kc_fe_selvar_1->ID_1;
	    {
		{
		    {
			const ID language = kc_selvar_0_1;

			long nr;
			l--;
			language->unparse(v_ccfile_printer,view_output_collection);
			for(nr=0;nr<ssize;nr++) {
			    static char buf[30];
			    unparseitems entry=string_collection[nr][l];
			    sprintf(buf,"/*%ld*/",nr);
			    v_ccfile_printer(buf,base_uview);
			    entry->unparse(v_ccfile_printer,view_output_collection);
			    v_ccfile_printer(",\n",base_uview);
			}
			v_ccfile_printer("};\n\n",base_uview);

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->languagenames_1;

	}
    }
    v_ccfile_printer("char **kc_language=kc_language_",base_uview);
    {
	languagenames kc_selvar_0_1 = phylum_cast<languagenames>((languagenames)Thelanguages);
	if ((kc_selvar_0_1->prod_sel() == sel_Conslanguagenames)) {
	    const ID l = (kc_selvar_0_1)->ID_1;

	    l->unparse(v_ccfile_printer,base_uview);

	} else
	    kc_no_default_in_with( "unparse_string_collection", __LINE__, __FILE__ );
    }
    v_ccfile_printer(";\n\n",base_uview);

}

phylumnames f_phylumnames_foreachwith_vars(idCexpressions a_idCexpressions)
{
    return t_f_phylumnames_foreachwith_vars(a_idCexpressions);

}

phylumnames t_f_phylumnames_foreachwith_vars(idCexpressions a_idCexpressions)
{{
	idCexpressions kc_selvar_0_1 = phylum_cast<idCexpressions>(a_idCexpressions);
	if ((kc_selvar_0_1->prod_sel() == sel_ConsidCexpressions) && ((kc_selvar_0_1)->idCexpression_1->prod_sel() == sel_IdCexpression)) {
	    const ID id = phylum_cast<const impl_idCexpression_IdCexpression*>((kc_selvar_0_1)->idCexpression_1)->ID_1;
	    const idCexpressions t = (kc_selvar_0_1)->idCexpressions_1;

	    return Consphylumnames(
		f_listelementphylum(id),
		t_f_phylumnames_foreachwith_vars( t ));

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_NilidCexpressions)) {
	    return Nilphylumnames(); 
	    	} else
	{ kc_no_default_in_with( "t_f_phylumnames_foreachwith_vars", __LINE__, __FILE__ );
	    return static_cast<phylumnames>(0); }
    }

}

phylumnames f_phylumnames_foreachwith_listvars(idCexpressions a_idCexpressions)
{
    return t_f_phylumnames_foreachwith_listvars(a_idCexpressions);

}

phylumnames t_f_phylumnames_foreachwith_listvars(idCexpressions a_idCexpressions)
{{
	idCexpressions kc_selvar_0_1 = phylum_cast<idCexpressions>(a_idCexpressions);
	if ((kc_selvar_0_1->prod_sel() == sel_ConsidCexpressions) && ((kc_selvar_0_1)->idCexpression_1->prod_sel() == sel_IdCexpression)) {
	    const ID id = phylum_cast<const impl_idCexpression_IdCexpression*>((kc_selvar_0_1)->idCexpression_1)->ID_1;
	    const idCexpressions t = (kc_selvar_0_1)->idCexpressions_1;

	    return Consphylumnames(
		id,
		t_f_phylumnames_foreachwith_listvars( t ));

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_NilidCexpressions)) {
	    return Nilphylumnames(); 
	    	} else
	{ kc_no_default_in_with( "t_f_phylumnames_foreachwith_listvars", __LINE__, __FILE__ );
	    return static_cast<phylumnames>(0); }
    }

}

void f_collect_members(fndeclarations fns)
{
    {
	fndeclarations kc_fe_selvar_1 =  fns;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consfndeclarations
	    ) {
	    fndeclaration kc_selvar_0_1 = kc_fe_selvar_1->fndeclaration_1;
	    {
		{
		    {
			const fndeclaration fn = kc_selvar_0_1;
			{
			    fndeclaration kc_selvar_1_1 = phylum_cast<fndeclaration>(fn);
			    if ((kc_selvar_1_1->prod_sel() == sel_FnAcDeclaration) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_class_qualifier_list_1->prod_sel() == sel_Consac_class_qualifier_list) && ((phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_class_qualifier_list_1)->ac_class_qualifier_list_1->prod_sel() == sel_Nilac_class_qualifier_list) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->fnclass_1->prod_sel() == sel_MemberFn)) {
				const ID id = (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_class_qualifier_list_1)->ID_1;

				phylumdeclaration ph_decl=f_phylumdeclofid(id);
				alternative op=f_alternativeofoperator(id);
				if(ph_decl)
				ph_decl->additional_members=Consfndeclarations(fn, ph_decl->additional_members);
				else if(op)
				op->additional_members=Consfndeclarations(fn, op->additional_members);

			    } else
				if ((kc_selvar_1_1->prod_sel() == sel_FnAcDeclaration) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcDirectDeclId) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->fnclass_1->prod_sel() == sel_DestructorFn)) {
				const ID id = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclId*>(phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1)->ID_1;

				phylumdeclaration ph_decl=f_phylumdeclofid(id);
				alternative op=f_alternativeofoperator(id);
				if(ph_decl)
				ph_decl->additional_members=Consfndeclarations(fn, ph_decl->additional_members);
				else if(op)
				op->additional_members=Consfndeclarations(fn, op->additional_members);

			    } else
				if ((kc_selvar_1_1->prod_sel() == sel_FnAcDeclaration) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcDirectDeclId) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->fnclass_1->prod_sel() == sel_ConstructorFn)) {
				const ID id = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclId*>(phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1)->ID_1;

				phylumdeclaration ph_decl=f_phylumdeclofid(id);
				alternative op=f_alternativeofoperator(id);
				if(ph_decl)
				ph_decl->additional_members=Consfndeclarations(fn, ph_decl->additional_members);
				else if(op)
				op->additional_members=Consfndeclarations(fn, op->additional_members);

			    } else
				if ((kc_selvar_1_1->prod_sel() == sel_FnAcDeclaration) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcConvOperatorDecl) && (phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->fnclass_1->prod_sel() == sel_ConvOperatorFn)) {
				const ID id = phylum_cast<const impl_ac_direct_declarator_AcConvOperatorDecl*>(phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_FnAcDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ac_direct_declarator_1)->ID_1;

				phylumdeclaration ph_decl=f_phylumdeclofid(id);
				alternative op=f_alternativeofoperator(id);
				if(ph_decl)
				ph_decl->additional_members=Consfndeclarations(fn, ph_decl->additional_members);
				else if(op)
				op->additional_members=Consfndeclarations(fn, op->additional_members);

			    } else
				if ((kc_selvar_1_1->prod_sel() == sel_AcMemberDeclaration) && (phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcMemberDecl)) {
				const ID id = phylum_cast<const impl_ac_direct_declarator_AcMemberDecl*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(phylum_cast<const impl_fndeclaration_AcMemberDeclaration*>(kc_selvar_1_1)->ac_declarator_1)->ac_direct_declarator_1)->ID_1;

				phylumdeclaration ph_decl=f_phylumdeclofid(id);
				alternative op=f_alternativeofoperator(id);
				if(ph_decl)
				ph_decl->additional_members=Consfndeclarations(fn, ph_decl->additional_members);
				else if(op)
				op->additional_members=Consfndeclarations(fn, op->additional_members);

			    } else
			    {

			    }
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->fndeclarations_1;

	}
    }

}

ID f_id_of_ctor_dtor_decl(ac_declarator decl)
{{
	ac_declarator kc_selvar_0_1 = phylum_cast<ac_declarator>(decl);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1)->ac_direct_declarator_1->prod_sel() == sel_AcDirectDeclId)) {
	    const ID id = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclId*>(phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1)->ac_direct_declarator_1)->ID_1;
	    return id; 
	    	} else
	{
	    return NULL; 
	}
    }

}

void prepare_base_classes(baseclass_declarations decls)
{
    {
	baseclass_declarations kc_fe_selvar_1 =  decls;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consbaseclass_declarations
	    ) {
	    baseclass_decl kc_selvar_0_1 = kc_fe_selvar_1->baseclass_decl_1;
	    {
		{
		    if ((kc_selvar_0_1->prod_sel() == sel_BaseClassDecl)) {
			const ID id = phylum_cast<const impl_baseclass_decl_BaseClassDecl*>(kc_selvar_0_1)->ID_1;
			const baseclass_list bases = phylum_cast<const impl_baseclass_decl_BaseClassDecl*>(kc_selvar_0_1)->baseclass_list_1;

			phylumdeclaration ph_decl=f_phylumdeclofid(id);
			alternative op=f_alternativeofoperator(id);
			if(ph_decl)
			ph_decl->base_classes=concat(bases, ph_decl->base_classes);
			else if(op)
			op->base_classes=concat(bases,op->base_classes);

		    } else
		    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->baseclass_declarations_1;

	}
    }

}


} // namespace kc
