/*
 * $Id$
 *
 * JSDAI(TM), a way to implement STEP, ISO 10303
 * Copyright (C) 1997-2008, LKSoftWare GmbH, Germany
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License
 * version 3 as published by the Free Software Foundation (AGPL v3).
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * JSDAI is a registered trademark of LKSoftWare GmbH, Germany
 * This software is also available under commercial licenses.
 * See also http://www.jsdai.net/
 */

/* Generated By:JJTree: Do not edit this line. X_ForeachExpr.java */

package jsdai.expressCompiler;

import java.util.*;
import java.io.*;
import jsdai.lang.*;


public class X_ForeachExpr extends SimpleNode {


  String foreach_variable_id;
  String foreach_variable_uid;
  String foreach_variable_scope_id;

	boolean outer;


  public X_ForeachExpr(int id) {
    super(id);
  }

  public X_ForeachExpr(Compiler2 p, int id) {
    super(p, id);
  }


  /** Accept the visitor. **/
  public Object jjtAccept(Compiler2Visitor visitor, Object data) throws jsdai.lang.SdaiException {
    return visitor.visit(this, data);
  }

	/*

		simple example: 

			names := FOR EACH a_name_111 IN all_names WHERE a_name_111 = 'kuku'; RETURN a_name_111;



NODE:        ForeachExpr
NODE:         Expression
NODE:          VariableRef - _e_all_names (test_for_each$all_names), reference depth: 1, declaration depth: 1
NODE:         WhereClause
NODE:          DomainRule
NODE:           DomainRuleLogicalExpression
NODE:            Expression
NODE:             RelOpExtended
NODE:              VariableRef - a_name_111 (test_for_each$1$a_name_111), reference depth: 1, declaration depth: 1
NODE:              Literal - "kuku"
NODE:         Expression
NODE:          VariableRef - a_name_111 (test_for_each$1$a_name_111), reference depth: 1, declaration depth: 1

			so, we have the following children:
			
			2 or 3 possible children, depending
			
			1. Expression - this is IN expression, the 1st node of type Expression and also the very 1st node absolutely
			2. WhereClause - optional, may be absent
			3. Expression - this is RETURN expression, the 2nd node of type Expression and also the very last node absolutely: 2nd or 3rd, but NOT 1st
			

	
	*/

  public Object childrenAccept(Compiler2Visitor visitor, Object data) throws SdaiException {
    JavaClass jc = (JavaClass) data;

    if (children != null) {
    	
			// these initializations are from SimpleNode, perhaps needed or not
      variable_names = new Vector();
      variable_declarations = new Vector();
      statements = new Vector();
      initializing_code = new Vector();

			Vector in_variable_names = new Vector();
			Vector in_variable_declarations = new Vector();
			Vector in_statements = new Vector();
			Vector in_initializing_code = new Vector();
			Vector in_forwarded_stuff = new Vector();
			String in_forwarded_java = "";
			String in_opening_java = "";
			String in_generated_java = "";
			String in_generated_java_2 = "";
			boolean in_move_up_java_statements = false;
			boolean in_print2string_activated = false;
			boolean in_java_contains_statements = false;

			Vector return_variable_names = new Vector();
			Vector return_variable_declarations = new Vector();
			Vector return_statements = new Vector();
			Vector return_initializing_code = new Vector();
			Vector return_forwarded_stuff = new Vector();
			String return_forwarded_java = "";
			String return_opening_java = "";
			String return_generated_java = "";
			String return_generated_java_2 = "";
			boolean return_move_up_java_statements = false;
			boolean return_print2string_activated = false;
			boolean return_java_contains_statements = false;

			Vector where_variable_names = new Vector();
			Vector where_variable_declarations = new Vector();
			Vector where_statements = new Vector();
			Vector where_initializing_code = new Vector();
			Vector where_forwarded_stuff = new Vector();
			String where_forwarded_java = "";
			String where_opening_java = "";
			String where_generated_java = "";
			String where_generated_java_2 = "";
			boolean where_move_up_java_statements = false;
			boolean where_print2string_activated = false;
			boolean where_java_contains_statements = false;

			boolean foreach_stack_pushed = false;

      for (int i = 0; i < children.length; ++i) {
        children[i].jjtAccept(visitor, data);

        if (jc != null) {
          if (jc.active) {
            if (children[i] instanceof X_Expression) {
							if (i == 0) { // IN expression

      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        in_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    in_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                in_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                in_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              in_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              in_generated_java_2 = jc.generated_java;
	              in_generated_java = ((SimpleNode) children[i]).generated_java;
                in_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                in_opening_java = ((SimpleNode) children[i]).opening_java;

								in_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";

							} else { // RETURN expression

      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        return_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    return_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                return_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                return_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              return_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              return_generated_java_2 = jc.generated_java;
	              return_generated_java = ((SimpleNode) children[i]).generated_java;
                return_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                return_opening_java = ((SimpleNode) children[i]).opening_java;

								return_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";


							}
						} else // if child = Expression   	
            if (children[i] instanceof X_WhereClause) { // optional



      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        where_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    where_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                where_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                where_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              where_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              where_generated_java_2 = jc.generated_java;
	              where_generated_java = ((SimpleNode) children[i]).generated_java;
	              ((SimpleNode) children[i]).generated_java = "";
                where_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                where_opening_java = ((SimpleNode) children[i]).opening_java;

								where_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";

							 jc.foreach_stack.push(jc.foreach_where);
							 foreach_stack_pushed = true;

            } else { // if child = WhereClause
							// INTERNAL ERROR
							System.out.println("Express-X compiler INTERNAL ERROR - ForeachExpr - 01 - child nr: " + i + ", node: " +  children[i]);
						} 
					} // if jc.active
				} // if jc != null
			} // for i: children
			
			// let's see what we got:
/*			
			System.out.println("<FOR EACH NODE> IN generated_java_2 : " +  in_generated_java_2);			
			System.out.println("<FOR EACH NODE> WHERE generated_java_2 : " +  where_generated_java_2);			
			System.out.println("<FOR EACH NODE> RETURN generated_java_2 : " +  return_generated_java_2);			

			System.out.println("<FOR EACH NODE> IN generated_java : " +  in_generated_java);			
			System.out.println("<FOR EACH NODE> WHERE generated_java : " +  where_generated_java);			
			System.out.println("<FOR EACH NODE> RETURN generated_java : " +  return_generated_java);			

			System.out.println("<FOR EACH NODE> IN forwarded_java : " +  in_forwarded_java);			
			System.out.println("<FOR EACH NODE> WHERE forwarded_java : " +  where_forwarded_java);			
			System.out.println("<FOR EACH NODE> RETURN forwarded_java : " +  return_forwarded_java);			

			System.out.println("<FOR EACH NODE> IN opening_java : " +  in_opening_java);			
			System.out.println("<FOR EACH NODE> WHERE opening_java : " +  where_opening_java);			
			System.out.println("<FOR EACH NODE> RETURN opening_java : " +  return_opening_java);			

			System.out.println("<FOR EACH NODE> IN forwarded_stuff : " +  in_forwarded_stuff);			
			System.out.println("<FOR EACH NODE> WHERE forwarded_stuff : " +  where_forwarded_stuff);			
			System.out.println("<FOR EACH NODE> RETURN forwarded_stuff : " +  return_forwarded_stuff);			

			System.out.println("<FOR EACH NODE> IN variable_names : " +  in_variable_names);			
			System.out.println("<FOR EACH NODE> WHERE variable_names : " +  where_variable_names);			
			System.out.println("<FOR EACH NODE> RETURN variable_names : " +  return_variable_names);			

			System.out.println("<FOR EACH NODE> IN variable_declarations : " +  in_variable_declarations);			
			System.out.println("<FOR EACH NODE> WHERE variable_declarations : " +  where_variable_declarations);			
			System.out.println("<FOR EACH NODE> RETURN variable_declarations : " +  return_variable_declarations);			

			System.out.println("<FOR EACH NODE> IN statements : " +  in_statements);			
			System.out.println("<FOR EACH NODE> WHERE statements : " +  where_statements);			
			System.out.println("<FOR EACH NODE> RETURN statements : " +  return_statements);			

			System.out.println("<FOR EACH NODE> IN initializing_code : " +  in_initializing_code);			
			System.out.println("<FOR EACH NODE> WHERE initializing_code : " +  where_initializing_code);			
			System.out.println("<FOR EACH NODE> RETURN initializing_code : " +  return_initializing_code);			



			System.out.println("<FOR EACH NODE> foreach_variable_id : " +  foreach_variable_id);			
			System.out.println("<FOR EACH NODE> foreach_variable_uid : " +  foreach_variable_uid);			
			System.out.println("<FOR EACH NODE> foreach_variable_scope_id : " +  foreach_variable_scope_id);			
*/

			for (int kk = 0; kk < jc.foreach_where.size(); kk++) {
//				System.out.println("<FOR EACH NODE> foreach_where index: " + kk + ", string: " +  (String)jc.foreach_where.elementAt(kk));			
			}


			/*
					result:
					
					<FOR EACH NODE> IN generated_java_2 : _e_all_names
					<FOR EACH NODE> WHERE generated_java_2 : _e_all_names
					<FOR EACH NODE> RETURN generated_java_2 : _implicit_1_a_name_111
		

<FOR EACH NODE> foreach_variable_id : a_name_111
<FOR EACH NODE> foreach_variable_uid : _implicit_1_a_name_111
<FOR EACH NODE> foreach_variable_scope_id : _implicit_1_
				
domain rule:

<DOMAIN RULE> :     return (Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getLogical());
  }

				
				
				
					FOR EACH expression:
		
						names := FOR EACH a_name_111 IN all_names WHERE a_name_111 = 'kuku'; RETURN a_name_111;
		
					equivalent QUERY expression:
					
						names := QUERY(the_name_222 <* all_names | the_name_222 = 'kuku');
					
				
					java, generated for equivalent QUERY expression:
					
											Value _internal_aggregate_source4 = _e_all_names;
											Value _result2 = Value.alloc(_internal_aggregate_source4).create();
											if (_internal_aggregate_source4.getActualJavaType() != Value.INDETERMINATE) {
												for (int _i3 = 1; _i3 <= _internal_aggregate_source4.getMemberCount(); _i3++) {
													Value _implicit_2_the_name_222 = _internal_aggregate_source4.getByIndex(_i3);
													if (Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_2_the_name_222, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku")).getLogical() == 2) {
														_result2.addMember(_context, _implicit_2_the_name_222);
													}
												}
											} else {
												_result2.unset();
											}

											_e_names.set(_context, _result2);
				
					java, that perhaps could be generated for FOR EACH expression:
					
											Value _internal_in_expression4 = _e_all_names;
											// possible different aggregate element type, defined by RETURN expression rather than IN expression, 
											// we may need to use AGGREGATE_GENERIC_TYPE because we may have difficulti knowing the type of element of result
											Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
											if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
												for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
													Value _implicit_1_a_name_111 = _internal_in_expression4.getByIndex(_i3);
                          // this condition should be the result of WHERE clause, 
                          // unfortunately, it is not WHERE logical_expression, 
                          // but where_clause with possibly multiple domain_rules with labels,  etc.
                          // probably WHERE logical_expression was really intended, but need to support the most complicated case
                         
                          if (---where_clause: all domain rules result it true, in their expressions _implicit_2_a_name_111 may be referenced) {
                         
														// according to part 14, it is not addMember, but union operator
														// _result2.addMember(_context, _implicit_2_the_name_222);
														// is union   operand1.union(operand2) or rather result.union(operand1, operand2) ?
														   _result2.addUnionOrConcatenate(_context, --return_expression--);
													}
												}
											} else {
												_result2.unset();
											}

											_e_names.set(_context, _result2);
						
		
				-----------------------------------------------------------------------------------------------------------------------------
				
				OK - here:
				
				names := FOR EACH a_name_111 IN all_names WHERE WR1: a_name_111 = 'kuku'; WR2: a_name_111 <> 'la-la'; RETURN a_name_111;

				
				pertinant generated stuff to be used:
				
				<FOR EACH NODE> IN generated_java_2 : _e_all_names
				<FOR EACH NODE> RETURN generated_java_2 : _implicit_1_a_name_111
	
				<FOR EACH NODE> foreach_where index: 0, string: Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getAsBoolean()
				<FOR EACH NODE> foreach_where index: 1, string: Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).nequal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "la-la"))).getAsBoolean()

	
				we want to generate:
				
				


					Value _internal_in_expression4 = _e_all_names;
					Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
					if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
						for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
							Value _implicit_1_a_name_111 = _internal_in_expression4.getByIndex(_i3);
              if (
									(Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getAsBoolean())        
									&& 
					        (Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).nequal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "la-la"))).getAsBoolean())      
					     ) {
								_result2.set(_context, Value.alloc().addOrUnionOrConcatenate(_context, _result2, (_result2)));
              
              }
                         
						}
					} else {
						_result2.unset();
					}

					_e_names.set(_context, _result2);
						

       -------------- or: 

					Value _internal_in_expression4 = in_generated_java_2;
					Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
					if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
						for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
							Value foreach_variable_uid = _internal_in_expression4.getByIndex(_i3);
              if (
									(foreach_where_0)        
									&& 
					        (foreach_where_1)      
					     ) {
								_result2.set(_context, Value.alloc().addOrUnionOrConcatenate(_context, _result2, (return_generated_java_2)));
              
              }
                         
						}
					} else {
						_result2.unset();
					}


		
					
			
			*/

      String iterator_name = "_iter" + (++uid);
      String result_name = "_result" + (++uid);
      String for_index = "_i" + (++uid);
			String str_in_expression = "_internal_in_expression" + (++uid);
	
			String str_where_clause = "";
			// add expressions for each domain_rule

			if (!foreach_stack_pushed) {
				 jc.foreach_stack.push(jc.foreach_where);
			}

			Vector foreach_vector = (Vector)jc.foreach_stack.pop();

			switch (foreach_vector.size()) {
//			switch (jc.foreach_where.size()) {
				case 0: // no where_clause or no domain_rules in where_clause, just generate if (true)
						str_where_clause = "true";
					break;
				case 1: // just one domain_rule, no need for &&
//						str_where_clause = (String)jc.foreach_where.elementAt(0);
						str_where_clause = (String)foreach_vector.elementAt(0);
					break;
				default: // multiple domain_rules, need to use && between their expressions
					boolean first_time = true;
//					for (int k1 = 0; k1 < jc.foreach_where.size(); k1++) {
					for (int k1 = 0; k1 < foreach_vector.size(); k1++) {
//						String str_current = (String)jc.foreach_where.elementAt(k1);
						String str_current = (String)foreach_vector.elementAt(k1);
						if (first_time) {
							first_time = false;
						} else {
							str_where_clause += "\n&&\n";
						}
						str_where_clause += "\n(" + str_current + ")\n";
					}
					break;		
			}			



      statements.addElement("Value " + str_in_expression + " = " + in_generated_java_2 + ";");

      String variable_declaration = "Value " + result_name + " = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();";

      statements.addElement(variable_declaration);


      statements.addElement("if (" + str_in_expression + ".getActualJavaType() != Value.INDETERMINATE) {");

      statements.addElement("\tfor (int " + for_index + " = 1; " + for_index + " <= " + str_in_expression + ".getMemberCount(); " + for_index + "++) {");

      statements.addElement("\t\tValue " + foreach_variable_uid + " = " + str_in_expression + ".getByIndex(" + for_index + ");");

			/*
			   try to add forwarding for nested support
			  
			*/


      if (in_java_contains_statements) {
        java_contains_statements = true;

        for (int j = 0; j < in_variable_names.size(); j++) {
          variable_names.add(in_variable_names.elementAt(j));
        }

        for (int j = 0; j < in_variable_declarations.size(); j++) {
          variable_declarations.add(in_variable_declarations.elementAt(j));
        }

        for (int j = 0; j < in_statements.size(); j++) {
          statements.add(in_statements.elementAt(j));
        }

        for (int j = 0; j < in_initializing_code.size(); j++) {
          initializing_code.add(in_initializing_code.elementAt(j));
        }
			}

      if (where_java_contains_statements) {
        java_contains_statements = true;

        for (int j = 0; j < where_variable_names.size(); j++) {
          variable_names.add(where_variable_names.elementAt(j));
        }

        for (int j = 0; j < where_variable_declarations.size(); j++) {
          variable_declarations.add(where_variable_declarations.elementAt(j));
        }

        for (int j = 0; j < where_statements.size(); j++) {
          statements.add(where_statements.elementAt(j));
        }

        for (int j = 0; j < where_initializing_code.size(); j++) {
          initializing_code.add(where_initializing_code.elementAt(j));
        }
			}

      if (return_java_contains_statements) {
        java_contains_statements = true;

        for (int j = 0; j < return_variable_names.size(); j++) {
          variable_names.add(return_variable_names.elementAt(j));
        }

        for (int j = 0; j < return_variable_declarations.size(); j++) {
          variable_declarations.add(return_variable_declarations.elementAt(j));
        }

        for (int j = 0; j < return_statements.size(); j++) {
          statements.add(return_statements.elementAt(j));
        }

        for (int j = 0; j < return_initializing_code.size(); j++) {
          initializing_code.add(return_initializing_code.elementAt(j));
        }
			}


      statements.addElement("\t\tif (" + str_where_clause + ") {");


//      statements.addElement("\t\t\t" + result_name + ".set(_context, Value.alloc().addOrUnionOrConcatenate(_context, " + result_name + ", (" + return_generated_java_2 + ")));");
// System.out.println("backend-ForEach --- outer: " + outer);
      if (outer) { 

				statements.addElement("\t\t\t" + result_name + ".unionEnlarge((" + return_generated_java_2 + "), _context);");
      } else {
	      statements.addElement("\t\t\t" + result_name + ".set(_context, Value.alloc().addOrUnionOrConcatenate(_context, " + result_name + ", (" + return_generated_java_2 + ")));");
      }
   
   
      statements.addElement("\t\t}");
      statements.addElement("\t}");

      statements.addElement("} else {");
      statements.addElement("\t" + result_name + ".unset();");
      statements.addElement("}");

      java_contains_statements = true;

      if (jc != null) {
        if (jc.active) {
          jc.generated_java = result_name;
        }
      }
			generated_java = "";





		} // if children != null	
    return data;
	} // method: childrenAccept


  public Object childrenAccept_no_nested(Compiler2Visitor visitor, Object data) throws SdaiException {


    JavaClass jc = (JavaClass) data;

    if (children != null) {
    	
			// these initializations are from SimpleNode, perhaps needed or not
      variable_names = new Vector();
      variable_declarations = new Vector();
      statements = new Vector();
      initializing_code = new Vector();

			Vector in_variable_names = new Vector();
			Vector in_variable_declarations = new Vector();
			Vector in_statements = new Vector();
			Vector in_initializing_code = new Vector();
			Vector in_forwarded_stuff = new Vector();
			String in_forwarded_java = "";
			String in_opening_java = "";
			String in_generated_java = "";
			String in_generated_java_2 = "";
			boolean in_move_up_java_statements = false;
			boolean in_print2string_activated = false;
			boolean in_java_contains_statements = false;

			Vector return_variable_names = new Vector();
			Vector return_variable_declarations = new Vector();
			Vector return_statements = new Vector();
			Vector return_initializing_code = new Vector();
			Vector return_forwarded_stuff = new Vector();
			String return_forwarded_java = "";
			String return_opening_java = "";
			String return_generated_java = "";
			String return_generated_java_2 = "";
			boolean return_move_up_java_statements = false;
			boolean return_print2string_activated = false;
			boolean return_java_contains_statements = false;

			Vector where_variable_names = new Vector();
			Vector where_variable_declarations = new Vector();
			Vector where_statements = new Vector();
			Vector where_initializing_code = new Vector();
			Vector where_forwarded_stuff = new Vector();
			String where_forwarded_java = "";
			String where_opening_java = "";
			String where_generated_java = "";
			String where_generated_java_2 = "";
			boolean where_move_up_java_statements = false;
			boolean where_print2string_activated = false;
			boolean where_java_contains_statements = false;


      for (int i = 0; i < children.length; ++i) {
        children[i].jjtAccept(visitor, data);

        if (jc != null) {
          if (jc.active) {
            if (children[i] instanceof X_Expression) {
							if (i == 0) { // IN expression

      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        in_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    in_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                in_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                in_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              in_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              in_generated_java_2 = jc.generated_java;
	              in_generated_java = ((SimpleNode) children[i]).generated_java;
                in_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                in_opening_java = ((SimpleNode) children[i]).opening_java;

								in_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";

							} else { // RETURN expression

      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        return_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    return_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                return_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                return_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              return_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              return_generated_java_2 = jc.generated_java;
	              return_generated_java = ((SimpleNode) children[i]).generated_java;
                return_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                return_opening_java = ((SimpleNode) children[i]).opening_java;

								return_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";


							}
						} else // if child = Expression   	
            if (children[i] instanceof X_WhereClause) { // optional



      	        if (((SimpleNode) children[i]).java_contains_statements) {
        	        where_java_contains_statements = true;

          	      // variable_declaration += "\n" + ((SimpleNode)children[i]).variable_declaration;
            	    for (int j = 0; j < ((SimpleNode) children[i]).variable_names.size(); j++) {
              	    where_variable_names.add(((SimpleNode) children[i]).variable_names.elementAt(j));
                	}

	                for (int j = 0; j < ((SimpleNode) children[i]).variable_declarations.size(); j++) {
  	                where_variable_declarations.add(((SimpleNode) children[i]).variable_declarations.elementAt(j));
    	            }

                	for (int j = 0; j < ((SimpleNode) children[i]).statements.size(); j++) {
  	                where_statements.add(((SimpleNode) children[i]).statements.elementAt(j));
    	            }

	                // initializing_code += "\n" + ((SimpleNode)children[i]).initializing_code;
  	              for (int j = 0; j < ((SimpleNode) children[i]).initializing_code.size(); j++) {
    	              where_initializing_code.add(((SimpleNode) children[i]).initializing_code.elementAt(j));
      	          }
        	      } // if contains statements

	              where_generated_java_2 = jc.generated_java;
	              where_generated_java = ((SimpleNode) children[i]).generated_java;
	              ((SimpleNode) children[i]).generated_java = "";
                where_forwarded_java = ((SimpleNode) children[i]).forwarded_java;
                where_opening_java = ((SimpleNode) children[i]).opening_java;

								where_forwarded_stuff = ((SimpleNode) children[i]).forwarded_stuff;

//  	            ((SimpleNode) children[i]).forwarded_java = "";



            } else { // if child = WhereClause
							// INTERNAL ERROR
							System.out.println("Express-X compiler INTERNAL ERROR - ForeachExpr - 01 - child nr: " + i + ", node: " +  children[i]);
						} 
					} // if jc.active
				} // if jc != null
			} // for i: children
			
			// let's see what we got:
	
/*	
			
			System.out.println("<FOR EACH NODE> IN generated_java_2 : " +  in_generated_java_2);			
			System.out.println("<FOR EACH NODE> WHERE generated_java_2 : " +  where_generated_java_2);			
			System.out.println("<FOR EACH NODE> RETURN generated_java_2 : " +  return_generated_java_2);			

			System.out.println("<FOR EACH NODE> IN generated_java : " +  in_generated_java);			
			System.out.println("<FOR EACH NODE> WHERE generated_java : " +  where_generated_java);			
			System.out.println("<FOR EACH NODE> RETURN generated_java : " +  return_generated_java);			

			System.out.println("<FOR EACH NODE> IN forwarded_java : " +  in_forwarded_java);			
			System.out.println("<FOR EACH NODE> WHERE forwarded_java : " +  where_forwarded_java);			
			System.out.println("<FOR EACH NODE> RETURN forwarded_java : " +  return_forwarded_java);			

			System.out.println("<FOR EACH NODE> IN opening_java : " +  in_opening_java);			
			System.out.println("<FOR EACH NODE> WHERE opening_java : " +  where_opening_java);			
			System.out.println("<FOR EACH NODE> RETURN opening_java : " +  return_opening_java);			

			System.out.println("<FOR EACH NODE> IN forwarded_stuff : " +  in_forwarded_stuff);			
			System.out.println("<FOR EACH NODE> WHERE forwarded_stuff : " +  where_forwarded_stuff);			
			System.out.println("<FOR EACH NODE> RETURN forwarded_stuff : " +  return_forwarded_stuff);			

			System.out.println("<FOR EACH NODE> IN variable_names : " +  in_variable_names);			
			System.out.println("<FOR EACH NODE> WHERE variable_names : " +  where_variable_names);			
			System.out.println("<FOR EACH NODE> RETURN variable_names : " +  return_variable_names);			

			System.out.println("<FOR EACH NODE> IN variable_declarations : " +  in_variable_declarations);			
			System.out.println("<FOR EACH NODE> WHERE variable_declarations : " +  where_variable_declarations);			
			System.out.println("<FOR EACH NODE> RETURN variable_declarations : " +  return_variable_declarations);			

			System.out.println("<FOR EACH NODE> IN statements : " +  in_statements);			
			System.out.println("<FOR EACH NODE> WHERE statements : " +  where_statements);			
			System.out.println("<FOR EACH NODE> RETURN statements : " +  return_statements);			

			System.out.println("<FOR EACH NODE> IN initializing_code : " +  in_initializing_code);			
			System.out.println("<FOR EACH NODE> WHERE initializing_code : " +  where_initializing_code);			
			System.out.println("<FOR EACH NODE> RETURN initializing_code : " +  return_initializing_code);			



			System.out.println("<FOR EACH NODE> foreach_variable_id : " +  foreach_variable_id);			
			System.out.println("<FOR EACH NODE> foreach_variable_uid : " +  foreach_variable_uid);			
			System.out.println("<FOR EACH NODE> foreach_variable_scope_id : " +  foreach_variable_scope_id);			

*/

			for (int kk = 0; kk < jc.foreach_where.size(); kk++) {
//				System.out.println("<FOR EACH NODE> foreach_where index: " + kk + ", string: " +  (String)jc.foreach_where.elementAt(kk));			
			}


			/*
					result:
					
					<FOR EACH NODE> IN generated_java_2 : _e_all_names
					<FOR EACH NODE> WHERE generated_java_2 : _e_all_names
					<FOR EACH NODE> RETURN generated_java_2 : _implicit_1_a_name_111
		

<FOR EACH NODE> foreach_variable_id : a_name_111
<FOR EACH NODE> foreach_variable_uid : _implicit_1_a_name_111
<FOR EACH NODE> foreach_variable_scope_id : _implicit_1_
				
domain rule:

<DOMAIN RULE> :     return (Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getLogical());
  }

				
				
				
					FOR EACH expression:
		
						names := FOR EACH a_name_111 IN all_names WHERE a_name_111 = 'kuku'; RETURN a_name_111;
		
					equivalent QUERY expression:
					
						names := QUERY(the_name_222 <* all_names | the_name_222 = 'kuku');
					
				
					java, generated for equivalent QUERY expression:
					
											Value _internal_aggregate_source4 = _e_all_names;
											Value _result2 = Value.alloc(_internal_aggregate_source4).create();
											if (_internal_aggregate_source4.getActualJavaType() != Value.INDETERMINATE) {
												for (int _i3 = 1; _i3 <= _internal_aggregate_source4.getMemberCount(); _i3++) {
													Value _implicit_2_the_name_222 = _internal_aggregate_source4.getByIndex(_i3);
													if (Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_2_the_name_222, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku")).getLogical() == 2) {
														_result2.addMember(_context, _implicit_2_the_name_222);
													}
												}
											} else {
												_result2.unset();
											}

											_e_names.set(_context, _result2);
				
					java, that perhaps could be generated for FOR EACH expression:
					
											Value _internal_in_expression4 = _e_all_names;
											// possible different aggregate element type, defined by RETURN expression rather than IN expression, 
											// we may need to use AGGREGATE_GENERIC_TYPE because we may have difficulti knowing the type of element of result
											Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
											if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
												for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
													Value _implicit_1_a_name_111 = _internal_in_expression4.getByIndex(_i3);
                          // this condition should be the result of WHERE clause, 
                          // unfortunately, it is not WHERE logical_expression, 
                          // but where_clause with possibly multiple domain_rules with labels,  etc.
                          // probably WHERE logical_expression was really intended, but need to support the most complicated case
                         
                          if (---where_clause: all domain rules result it true, in their expressions _implicit_2_a_name_111 may be referenced) {
                         
														// according to part 14, it is not addMember, but union operator
														// _result2.addMember(_context, _implicit_2_the_name_222);
														// is union   operand1.union(operand2) or rather result.union(operand1, operand2) ?
														   _result2.addUnionOrConcatenate(_context, --return_expression--);
													}
												}
											} else {
												_result2.unset();
											}

											_e_names.set(_context, _result2);
						
		
				-----------------------------------------------------------------------------------------------------------------------------
				
				OK - here:
				
				names := FOR EACH a_name_111 IN all_names WHERE WR1: a_name_111 = 'kuku'; WR2: a_name_111 <> 'la-la'; RETURN a_name_111;

				
				pertinant generated stuff to be used:
				
				<FOR EACH NODE> IN generated_java_2 : _e_all_names
				<FOR EACH NODE> RETURN generated_java_2 : _implicit_1_a_name_111
	
				<FOR EACH NODE> foreach_where index: 0, string: Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getAsBoolean()
				<FOR EACH NODE> foreach_where index: 1, string: Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).nequal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "la-la"))).getAsBoolean()

	
				we want to generate:
				
				


					Value _internal_in_expression4 = _e_all_names;
					Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
					if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
						for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
							Value _implicit_1_a_name_111 = _internal_in_expression4.getByIndex(_i3);
              if (
									(Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).equal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "kuku"))).getAsBoolean())        
									&& 
					        (Value.alloc(ExpressTypes.LOGICAL_TYPE).set(_context, Value.alloc(ExpressTypes.LOGICAL_TYPE).nequal(_context, _implicit_1_a_name_111, Value.alloc(ExpressTypes.STRING_TYPE).set(_context, "la-la"))).getAsBoolean())      
					     ) {
								_result2.set(_context, Value.alloc().addOrUnionOrConcatenate(_context, _result2, (_result2)));
              
              }
                         
						}
					} else {
						_result2.unset();
					}

					_e_names.set(_context, _result2);
						

       -------------- or: 

					Value _internal_in_expression4 = in_generated_java_2;
					Value _result2 = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();
					if (_internal_in_expression4.getActualJavaType() != Value.INDETERMINATE) {
						for (int _i3 = 1; _i3 <= _internal_in_expression4.getMemberCount(); _i3++) {
							Value foreach_variable_uid = _internal_in_expression4.getByIndex(_i3);
              if (
									(foreach_where_0)        
									&& 
					        (foreach_where_1)      
					     ) {
								_result2.set(_context, Value.alloc().addOrUnionOrConcatenate(_context, _result2, (return_generated_java_2)));
              
              }
                         
						}
					} else {
						_result2.unset();
					}


		
					
			
			*/

      String iterator_name = "_iter" + (++uid);
      String result_name = "_result" + (++uid);
      String for_index = "_i" + (++uid);
			String str_in_expression = "_internal_in_expression" + (++uid);
	
			String str_where_clause = "";
			// add expressions for each domain_rule
			switch (jc.foreach_where.size()) {
				case 0: // no where_clause or no domain_rules in where_clause, just generate if (true)
						str_where_clause = "true";
					break;
				case 1: // just one domain_rule, no need for &&
						str_where_clause = (String)jc.foreach_where.elementAt(0);
					break;
				default: // multiple domain_rules, need to use && between their expressions
					boolean first_time = true;
					for (int k1 = 0; k1 < jc.foreach_where.size(); k1++) {
						String str_current = (String)jc.foreach_where.elementAt(k1);
						if (first_time) {
							first_time = false;
						} else {
							str_where_clause += "\n&&\n";
						}
						str_where_clause += "\n(" + str_current + ")\n";
					}
					break;		
			}			


      statements.addElement("Value " + str_in_expression + " = " + in_generated_java_2 + ";");

      String variable_declaration = "Value " + result_name + " = Value.alloc(ExpressTypes.AGGREGATE_GENERIC_TYPE).create();";

      statements.addElement(variable_declaration);


      statements.addElement("if (" + str_in_expression + ".getActualJavaType() != Value.INDETERMINATE) {");

      statements.addElement("\tfor (int " + for_index + " = 1; " + for_index + " <= " + str_in_expression + ".getMemberCount(); " + for_index + "++) {");

      statements.addElement("\t\tValue " + foreach_variable_uid + " = " + str_in_expression + ".getByIndex(" + for_index + ");");


      statements.addElement("\t\tif (" + str_where_clause + ") {");

      
// System.out.println("backend-ForEach - outer: " + outer);
      if (outer) { 

				statements.addElement("\t\t\t" + result_name + ".unionEnlarge((" + return_generated_java_2 + "), _context);");
      } else {
	      statements.addElement("\t\t\t" + result_name + ".set(_context, Value.alloc().addOrUnionOrConcatenate(_context, " + result_name + ", (" + return_generated_java_2 + ")));");
      }
     


      statements.addElement("\t\t}");
      statements.addElement("\t}");

      statements.addElement("} else {");
      statements.addElement("\t" + result_name + ".unset();");
      statements.addElement("}");

      java_contains_statements = true;

      if (jc != null) {
        if (jc.active) {
          jc.generated_java = result_name;
        }
      }
			generated_java = "";





		} // if children != null	
    return data;
	}  // method declaration





}
