gen::add_generator "C#" gen_cs::generate

namespace eval gen_cs {


variable invoke_cleanup ""
variable link_to_final_found 0


variable cs_keywords {
abstract
as
base
bool
break
byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
else
enum
event
explicit
extern
false
finally
fixed
float
for
foreach
goto
if
implicit
in
int
interface
internal
is
lock
long
namespace
new
null
object
operator
out
override
params
private
protected
public
readonly
ref
return
sbyte
sealed
short
sizeof
stackalloc
static
string
struct
switch
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
virtual
void
volatile
while

add
alias
ascending
async
await
descending
dynamic
from
get
global
group
into
join
let
orderby
partial
remove
select
set
value
var
where
yield

}

# Autogenerated with DRAKON Editor 1.31

proc bad_case { switch_var select_icon_number } {
    #item 1308
    if {[ string compare -nocase $switch_var "select" ] == 0} {
        #item 1311
        return "throw new InvalidOperationException\(\"Condition was not detected.\");"
    } else {
        #item 573
        return "throw new InvalidOperationException\(\"Not expected:  \" + ${switch_var}.ToString()\);"
    }
}

proc change_state { next_state machine_name returns } {
    #item 1744
    variable invoke_cleanup
    variable link_to_final_found
    #item 1095
    if {$next_state == ""} {
        #item 1745
        set link_to_final_found 1
        #item 1099
        set change $invoke_cleanup
    } else {
        #item 1098
        set change "State = StateNames.${next_state};"
    }
    #item 1815
    if {$returns == ""} {
        #item 1818
        return "$change\nreturn null;"
    } else {
        #item 1820
        set output [ lindex $returns 1 ]
        #item 1819
        return "$change\n$output"
    }
}

proc classify_keywords { keywords name } {
    #item 788
    set errors {}
    #item 742
    set access [ gen_cpp::find_keywords $keywords { private public protected internal } ]
    #item 7500000
    set _sw7500000_ [ llength $access ]
    #item 7500001
    if {($_sw7500000_ == 0) || ($_sw7500000_ == 1)} {
        
    } else {
        #item 744
        lappend errors "$name: inconsistent access: $access"
    }
    #item 746
    set dispatch [ gen_cpp::find_keywords $keywords { override abstract static virtual } ]
    #item 7620000
    set _sw7620000_ [ llength $dispatch ]
    #item 7620001
    if {$_sw7620000_ == 0} {
        #item 761
        set dispatch "normal"
    } else {
        #item 7620002
        if {$_sw7620000_ == 1} {
            
        } else {
            #item 754
            lappend errors "$name: inconsistent dispatch: $dispatch"
        }
    }
    #item 772
    set subtype [ gen_cpp::find_keywords $keywords { method ctr } ]
    #item 7730000
    set _sw7730000_ [ llength $subtype ]
    #item 7730001
    if {$_sw7730000_ == 0} {
        #item 771
        set subtype "method"
    } else {
        #item 7730002
        if {$_sw7730000_ == 1} {
            
        } else {
            #item 764
            lappend errors "$name: inconsistent method type: $subtype"
        }
    }
    #item 7750001
    if {(($subtype == "method") || (!($subtype == "ctr"))) || ($dispatch == "normal")} {
        
    } else {
        #item 820
        lappend errors \
        "$name: constructor cannot be $dispatch"
    }
    #item 837
    if {$access == ""} {
        #item 838
        set access "none"
    } else {
        
    }
    #item 866
    array set props {}
    #item 867
    set props(access) $access
    set props(dispatch) $dispatch
    set props(type) $subtype
    #item 868
    set proplist [ array get props ]
    set error_message [ join $errors "\n" ]
    #item 869
    return [ list $error_message $proplist ]
}

proc extract_body { comments } {
    #item 1849
    set body {}
    set inherits ""
    foreach comment $comments {
        #item 1850
        set state "idle"
        #item 1669
        set trimmed [ string trim $comment ]
        set lines [ split $trimmed "\n" ]
        foreach line $lines {
            #item 1872
            set line [ string trim $line ]
            set section [ string map {" " {}} $line ]
            #item 1874
            if {$line == ""} {
                
            } else {
                #item 18510001
                if {$state == "idle"} {
                    #item 1670
                    if {($section == "===fields===") || ($section == "===body===")} {
                        #item 1858
                        set state "fields"
                    } else {
                        #item 1862
                        if {$section == "===inherits==="} {
                            #item 1865
                            set state "inherits"
                        } else {
                            
                        }
                    }
                } else {
                    #item 18510002
                    if {$state == "fields"} {
                        #item 1867
                        if {$section == "===inherits==="} {
                            #item 1868
                            set state "inherits"
                        } else {
                            #item 1869
                            lappend body $line
                        }
                    } else {
                        #item 18510003
                        if {$state == "inherits"} {
                            
                        } else {
                            #item 18510004
                            error "Unexpected switch value: $state"
                        }
                        #item 1863
                        set inherits $line
                        #item 1864
                        set state "idle"
                    }
                }
            }
        }
    }
    #item 1873
    set body_txt [ join $body "\n        " ]
    #item 1673
    return [ list $body_txt $inherits ]
}

proc extract_class_name { section } {
    #item 957
    set section [ string map { "\{" " " } $section ]
    set section [ split $section " \t\n" ]
    #item 940
    set count [ llength $section ]
    #item 941
    if {$count < 2} {
        #item 955
        return ""
    } else {
        #item 944
        set found [ lsearch $section "class" ]
        #item 945
        if {$found == -1} {
            #item 949
            set found [ lsearch $section "struct" ]
            #item 950
            if {$found == -1} {
                #item 955
                return ""
            } else {
                #item 951
                set name_pos [ expr { $found + 1 } ]
                #item 954
                if {$name_pos < $count} {
                    #item 956
                    return [ lindex $section $name_pos ]
                } else {
                    #item 955
                    return ""
                }
            }
        } else {
            #item 951
            set name_pos [ expr { $found + 1 } ]
            #item 954
            if {$name_pos < $count} {
                #item 956
                return [ lindex $section $name_pos ]
            } else {
                #item 955
                return ""
            }
        }
    }
}

proc extract_many_cs_machines { gdb callbacks } {
    #item 1762
    variable invoke_cleanup
    variable link_to_final_found
    #item 1760
    set result {}
    #item 1751
    set diagrams [ $gdb eval {
    	select diagram_id from diagrams } ]
    foreach diagram_id $diagrams {
        #item 1754
        if {[graph::is_machine $diagram_id]} {
            #item 1767
            set link_to_final_found 0
            #item 1768
            set invoke_cleanup "Shutdown\(\);"
            #item 1759
            set info [ sma::build_machine $gdb $diagram_id $callbacks ]
            #item 1758
            sma::delete_diagram $gdb $diagram_id
            #item 1772
            lappend info "has_final" $link_to_final_found
            #item 1757
            lappend result $info
        } else {
            
        }
    }
    #item 1761
    return $result
}

proc extract_signature { text name } {
    #item 710
    array set props { 
    	access none 
    	dispatch normal
    	type method
    }
    set error_message ""
    set parameters {}
    set returns ""
    set type "method"
    #item 669
    set lines [ gen::separate_from_comments $text ]
    #item 671
    if {[ llength $lines ] == 0} {
        
    } else {
        #item 670
        set first_line [ lindex $lines 0 ]
        set first [ lindex $first_line 0 ]
        #item 693
        if {$first == "#comment"} {
            #item 683
            set type "comment"
        } else {
            #item 699
            set keywords { 
            	public private protected internal
            	override abstract static virtual
            	method ctr
            }
            #item 700
            set found_keywords [ gen_cpp::find_keywords $first $keywords ]
            #item 698
            if {[ llength $found_keywords ] == 0} {
                #item 702
                set start_index 0
                #item 678
                set count [ llength $lines ]
                #item 6810001
                set i $start_index
                while { 1 } {
                    #item 6810002
                    if {$i < $count} {
                        
                    } else {
                        break
                    }
                    #item 680
                    set current [ lindex $lines $i ]
                    set stripped [ lindex $current 0 ]
                    #item 686
                    if {[ string match "returns *" $stripped ]} {
                        #item 888
                        set returns [ gen_cpp::extract_return_type $stripped ]
                    } else {
                        #item 685
                        lappend parameters $current
                    }
                    #item 6810003
                    incr i
                }
            } else {
                #item 701
                set start_index 1
                #item 704
                set alien_keywords [ gen_cpp::find_not_belonging $first $keywords ]
                #item 705
                if {[ llength $alien_keywords ] == 0} {
                    #item 711
                    lassign [ classify_keywords $found_keywords $name ] \
                    	error_message prop_list
                    #item 712
                    if {$error_message == ""} {
                        #item 713
                        array unset props
                        array set props $prop_list
                        set type $props(type)
                        #item 678
                        set count [ llength $lines ]
                        #item 6810001
                        set i $start_index
                        while { 1 } {
                            #item 6810002
                            if {$i < $count} {
                                
                            } else {
                                break
                            }
                            #item 680
                            set current [ lindex $lines $i ]
                            set stripped [ lindex $current 0 ]
                            #item 686
                            if {[ string match "returns *" $stripped ]} {
                                #item 888
                                set returns [ gen_cpp::extract_return_type $stripped ]
                            } else {
                                #item 685
                                lappend parameters $current
                            }
                            #item 6810003
                            incr i
                        }
                    } else {
                        
                    }
                } else {
                    #item 706
                    set error_message \
                        "$name: Unexpected keywords: $alien_keywords"
                }
            }
        }
    }
    #item 897
    if {$type == "ctr"} {
        #item 898
        if {$returns == ""} {
            
        } else {
            #item 899
            set error_message \
            "$name: constructors must not have return type"
        }
    } else {
        #item 902
        if {$returns == ""} {
            #item 905
            set returns "void"
        } else {
            
        }
    }
    #item 714
    set prop_list [ array get props ]
    #item 682
    set signature [ gen::create_signature $type $prop_list $parameters $returns ]
    set result [ list $error_message $signature ]
    #item 896
    return $result
}

proc find_function_by_name { functions name } {
    foreach function $functions {
        #item 1651
        lassign $function diagram_id fname
        #item 1648
        if {$fname == $name} {
            #item 1652
            return $function
        } else {
            
        }
    }
    #item 1653
    return {}
}

proc foreach_check { item_id first second } {
    #item 1057
    set iter_var "_it$item_id"
    #item 1055
    return "$iter_var.MoveNext()"
}

proc foreach_current { item_id first second } {
    #item 1059
    lassign [ parse_foreach $item_id $first ] type var
    #item 1058
    set iter_var "_it$item_id"
    
    return "$var = $iter_var.Current;"
}

proc foreach_declare { item_id first second } {
    #item 1067
    lassign [ parse_foreach $item_id $first ] type var
    #item 1066
    set iter_var "_it$item_id"
    set iter_type "IEnumerator<$type>"
    
    
    return "$iter_type $iter_var = null;\n$type $var = default\($type\);"
}

proc foreach_incr { item_id first second } {
    #item 32
    return ""
}

proc foreach_init { item_id first second } {
    #item 1054
    lassign [ parse_foreach $item_id $first ] type var
    #item 19
    set iter_var "_it$item_id"
    set col_type "IEnumerable<$type>"
    
    
    return "$iter_var = \(\($col_type\)$second\).GetEnumerator();"
}

proc generate { db gdb filename } {
    #item 337
    set callbacks [ make_callbacks ]
    #item 1252
    lassign [ gen::scan_file_description $db \
     { header class footer } ] \
     header class footer
    #item 1532
    set raw_machines [ extract_many_cs_machines \
     $gdb $callbacks ]
    #item 1089
    set diagrams [ $gdb eval {
    	select diagram_id from diagrams } ]
    foreach diagram_id $diagrams {
        #item 1248
        if {[mwc::is_drakon $diagram_id]} {
            #item 1086
            gen::fix_graph_for_diagram $gdb $callbacks 1 $diagram_id
        } else {
            
        }
    }
    #item 1243
    tab::generate_tables $gdb $callbacks 0
    #item 1244
    if {[graph::errors_occured]} {
        
    } else {
        #item 349
        set nogoto 1
        set all_functions [ gen::generate_functions \
         $db $gdb $callbacks $nogoto ]
        #item 338
        if {[ graph::errors_occured ]} {
            
        } else {
            #item 1917
            if {$class == ""} {
                #item 1920
                set class_name ""
                #item 1254
                separate_methods $gdb $all_functions functions methods
                #item 1587
                set machines [ sma::add_handlers $gdb $raw_machines \
                 $all_functions ]
                #item 339
                set hfile [ replace_extension $filename "cs" ]
                set fhandle [ open_output_file $hfile ]
                catch {
                	p.print_to_file $fhandle $functions \
                		$methods \
                		$header $class $class_name $footer \
                		$machines
                } error_message
                set details $::errorInfo
                catch { close $fhandle }
                #item 340
                if {$error_message == ""} {
                    
                } else {
                    #item 1253
                    puts $details
                    #item 341
                    error $error_message
                }
            } else {
                #item 927
                set class_name [ extract_class_name $class ]
                #item 928
                if {$class_name == ""} {
                    #item 929
                    error \
                    "Class or struct is missing in the ===class=== section."
                } else {
                    #item 1254
                    separate_methods $gdb $all_functions functions methods
                    #item 1587
                    set machines [ sma::add_handlers $gdb $raw_machines \
                     $all_functions ]
                    #item 339
                    set hfile [ replace_extension $filename "cs" ]
                    set fhandle [ open_output_file $hfile ]
                    catch {
                    	p.print_to_file $fhandle $functions \
                    		$methods \
                    		$header $class $class_name $footer \
                    		$machines
                    } error_message
                    set details $::errorInfo
                    catch { close $fhandle }
                    #item 340
                    if {$error_message == ""} {
                        
                    } else {
                        #item 1253
                        puts $details
                        #item 341
                        error $error_message
                    }
                }
            }
        }
    }
}

proc generate_body { gdb diagram_id start_item node_list items incoming } {
    #item 590
    set callbacks [ make_callbacks ]
    #item 591
    return [ cbody::generate_body $gdb $diagram_id $start_item $node_list \
    $items $incoming $callbacks ]
}

proc get_message_constants { name messages } {
    #item 1887
    set state "none"
    set constants {}
    set names {}
    set i 1
    foreach message $messages {
        #item 1891
        set parts [ split $message "." ]
        set last [ lindex $parts end ]
        set count [ llength $parts ]
        lappend names $last
        #item 18920001
        if {$state == "none"} {
            #item 1899
            if {$count == 1} {
                #item 1912
                lappend constants \
                 [ list $message $i ]
                #item 1902
                set state "internal"
            } else {
                #item 1913
                lappend constants \
                 [ list $last $message ]
                #item 1903
                set state "external"
            }
        } else {
            #item 18920002
            if {$state == "internal"} {
                #item 1908
                if {$count == 1} {
                    #item 1914
                    lappend constants \
                     [ list $message $i ]
                } else {
                    #item 1910
                    error "Cannot combine external and internal message codes: $name"
                }
            } else {
                #item 18920003
                if {$state == "external"} {
                    
                } else {
                    #item 18920004
                    error "Unexpected switch value: $state"
                }
                #item 1906
                if {$count == 1} {
                    #item 1911
                    error "Cannot combine external and internal message codes: $name"
                } else {
                    #item 1915
                    lappend constants \
                     [ list $last $message ]
                }
            }
        }
        #item 1904
        incr i
    }
    #item 1890
    return [list $names $constants]
}

proc handle_message { fhandle ind states message names handlers } {
    #item 1727
    puts $fhandle "$ind            switch \(State\) \{"
    foreach state $states {
        #item 1742
        set message2 [ string map { - _ . _ } $message ]
        #item 1729
        set method "${state}_${message2}"
        #item 1733
        puts $fhandle "$ind                case StateNames.$state:"
        #item 1730
        if {[ find_function_by_name $handlers $method ] == {}} {
            
        } else {
            #item 1728
            puts $fhandle "$ind                    return $method\($names\);"
        }
    }
    #item 1726
    puts $fhandle "$ind                default:"
    puts $fhandle "$ind                    return null;"
    puts $fhandle "$ind            \}"
}

proc highlight { tokens } {
    #item 1509
    variable cs_keywords
    #item 1510
    return [ highlight_generic $cs_keywords $tokens ]
}

proc highlight_generic { keywords tokens } {
    #item 1359
    set result {}
    #item 1361
    set state "idle"
    foreach token $tokens {
        #item 1328
        lassign $token type text
        #item 13290001
        if {$state == "idle"} {
            #item 1476
            set state [ idle_default $keywords result $type $text ]
        } else {
            #item 13290002
            if {$state == "string"} {
                #item 1407
                lappend result $colors::syntax_string
                #item 14000001
                if {$text == "\""} {
                    #item 1408
                    set state "idle"
                } else {
                    #item 14000002
                    if {$text == "\\"} {
                        #item 1409
                        set state "escaping"
                    } else {
                        #item 14000003
                        if {$text == "\n"} {
                            #item 1503
                            set state "idle"
                        } else {
                            
                        }
                    }
                }
            } else {
                #item 13290003
                if {$state == "escaping"} {
                    #item 1411
                    lappend result $colors::syntax_string
                    #item 1526
                    if {$text == "\n"} {
                        #item 1528
                        set state "idle"
                    } else {
                        #item 1410
                        set state "string"
                    }
                } else {
                    #item 13290004
                    if {$state == "comment start"} {
                        #item 14390001
                        if {$text == "*"} {
                            #item 1447
                            set state "comment"
                            #item 1446
                            lappend result $colors::syntax_comment \
                            	$colors::syntax_comment
                        } else {
                            #item 14390002
                            if {$text == "/"} {
                                #item 1449
                                set state "comment line"
                                #item 1446
                                lappend result $colors::syntax_comment \
                                	$colors::syntax_comment
                            } else {
                                #item 1450
                                lappend result $colors::syntax_operator
                                #item 1451
                                set state [ idle_default $keywords result $type $text ]
                            }
                        }
                    } else {
                        #item 13290005
                        if {$state == "comment"} {
                            #item 1452
                            lappend result $colors::syntax_comment
                            #item 1453
                            if {$text == "*"} {
                                #item 1455
                                set state "comment end"
                            } else {
                                
                            }
                        } else {
                            #item 13290006
                            if {$state == "comment end"} {
                                #item 1459
                                lappend result $colors::syntax_comment
                                #item 1456
                                if {$text == "/"} {
                                    #item 1458
                                    set state "idle"
                                } else {
                                    
                                }
                            } else {
                                #item 13290007
                                if {$state == "comment line"} {
                                    #item 1463
                                    lappend result $colors::syntax_comment
                                    #item 1460
                                    if {$text == "\n"} {
                                        #item 1462
                                        set state "idle"
                                    } else {
                                        
                                    }
                                } else {
                                    #item 13290008
                                    if {$state == "char"} {
                                        #item 1471
                                        lappend result $colors::syntax_string
                                        #item 14640001
                                        if {$text == "'"} {
                                            #item 1472
                                            set state "idle"
                                        } else {
                                            #item 14640002
                                            if {$text == "\\"} {
                                                #item 1473
                                                set state "char escaping"
                                            } else {
                                                #item 14640003
                                                if {$text == "\n"} {
                                                    #item 1500
                                                    set state "idle"
                                                } else {
                                                    
                                                }
                                            }
                                        }
                                    } else {
                                        #item 13290009
                                        if {$state == "char escaping"} {
                                            #item 1475
                                            lappend result \
                                              $colors::syntax_string
                                            #item 1523
                                            if {$text == "\n"} {
                                                #item 1525
                                                set state "idle"
                                            } else {
                                                #item 1474
                                                set state "char"
                                            }
                                        } else {
                                            #item 13290010
                                            if {$state == "verbatim start"} {
                                                #item 1481
                                                if {$text == "\""} {
                                                    #item 1485
                                                    lappend result $colors::syntax_string \
                                                    	$colors::syntax_string
                                                    #item 1486
                                                    set state "verbatim"
                                                } else {
                                                    #item 1483
                                                    lappend result $colors::syntax_operator
                                                    #item 1511
                                                    set state [ idle_default $keywords result $type $text ]
                                                }
                                            } else {
                                                #item 13290011
                                                if {$state == "verbatim"} {
                                                    #item 1487
                                                    lappend result $colors::syntax_string
                                                    #item 1488
                                                    if {$text == "\""} {
                                                        #item 1490
                                                        set state "verbatim end"
                                                    } else {
                                                        
                                                    }
                                                } else {
                                                    #item 13290012
                                                    if {$state == "verbatim end"} {
                                                        
                                                    } else {
                                                        #item 13290013
                                                        error "Unexpected switch value: $state"
                                                    }
                                                    #item 1494
                                                    if {$text == "\""} {
                                                        #item 1495
                                                        lappend result $colors::syntax_string
                                                        #item 1496
                                                        set state "verbatim"
                                                    } else {
                                                        #item 1512
                                                        set state [ idle_default $keywords result $type $text ]
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    #item 15130001
    if {($state == "comment start") || ($state == "verbatim start")} {
        #item 1522
        lappend result $colors::syntax_operator
    } else {
        
    }
    #item 1360
    return $result
}

proc idle_default { keywords result_name type text } {
    #item 1417
    upvar 1 $result_name result
    #item 14180001
    if {$text == "\""} {
        #item 1429
        lappend result $colors::syntax_string
        #item 1435
        set state "string"
    } else {
        #item 14180002
        if {$text == "'"} {
            #item 1430
            lappend result $colors::syntax_string
            #item 1431
            set state "char"
        } else {
            #item 14180003
            if {$text == "/"} {
                #item 1432
                set state "comment start"
            } else {
                #item 14180004
                if {$text == "@"} {
                    #item 1433
                    set state "verbatim start"
                } else {
                    #item 1434
                    lappend result [standard_color $keywords $type $text]
                    #item 1436
                    set state "idle"
                }
            }
        }
    }
    #item 1438
    return $state
}

proc is_ctr { method } {
    #item 911
    set signature [ lindex $method 2 ]
    set type [ lindex $signature 0 ]
    return [ expr { $type == "ctr" } ]
}

proc is_weak { machine } {
    #item 1688
    set params [ dict get $machine "parameters" ]
    #item 1689
    if {[ llength $params ] == 1} {
        #item 1694
        set first [ lindex $params 0 ]
        #item 1693
        if {$first == "state machine"} {
            #item 1692
            return 1
        } else {
            #item 1687
            return 0
        }
    } else {
        #item 1687
        return 0
    }
}

proc make_callbacks { } {
    #item 641
    set callbacks {}
    
    gen::put_callback callbacks assign			gen_java::assign
    gen::put_callback callbacks compare			gen_java::compare
    gen::put_callback callbacks compare2		gen_java::compare
    gen::put_callback callbacks while_start 	gen_java::while_start
    gen::put_callback callbacks if_start		gen_java::if_start
    gen::put_callback callbacks elseif_start	gen_java::elseif_start
    gen::put_callback callbacks if_end			gen_java::if_end
    gen::put_callback callbacks else_start		gen_java::else_start
    gen::put_callback callbacks pass			gen_java::pass
    gen::put_callback callbacks continue		gen_java::p.continue
    gen::put_callback callbacks return_none		gen_java::return_none
    gen::put_callback callbacks block_close		gen_java::block_close
    gen::put_callback callbacks comment			gen_java::commentator
    
    gen::put_callback callbacks break			"break;"
    gen::put_callback callbacks and				gen_java::p.and
    gen::put_callback callbacks or				gen_java::p.or
    gen::put_callback callbacks not				gen_java::p.not
    gen::put_callback callbacks declare		gen_java::p.declare
    
    
    gen::put_callback callbacks bad_case		gen_cs::bad_case
    
    gen::put_callback callbacks body			gen_cs::generate_body
    gen::put_callback callbacks signature		gen_cs::extract_signature
    	
    gen::put_callback callbacks for_check		gen_cs::foreach_check
    gen::put_callback callbacks for_current		gen_cs::foreach_current
    gen::put_callback callbacks for_init		gen_cs::foreach_init
    gen::put_callback callbacks for_incr		gen_cs::foreach_incr
    gen::put_callback callbacks for_declare		gen_cs::foreach_declare
    gen::put_callback callbacks shelf gen_cs::shelf
    gen::put_callback callbacks change_state gen_cs::change_state
    gen::put_callback callbacks shutdown "Shutdown"
    gen::put_callback callbacks fsm_merge   0
    gen::put_callback callbacks native_foreach gen_cs::native_foreach
    #item 650
    return $callbacks
}

proc method_of_access { procedure access } {
    #item 1041
    set signature [ lindex $procedure 2 ]
    set type [ lindex $signature 0 ]
    #item 918
    if {$type == "method"} {
        #item 923
        set props_list [ lindex $signature 1 ]
        array set props $props_list
        #item 924
        if {$props(access) == $access} {
            #item 921
            return 1
        } else {
            #item 922
            return 0
        }
    } else {
        #item 922
        return 0
    }
}

proc native_foreach { for_it for_var } {
    #item 1814
    return "foreach ($for_it in $for_var) \{"
}

proc p.print_proc { weak_signature fhandle procedure class_name depth } {
    #item 97
    lassign $procedure diagram_id name signature body
    #item 968
    if {$class_name == ""} {
        
    } else {
        #item 971
        set name $class_name
    }
    #item 972
    lassign $signature type prop_list parameters returns
    array set props $prop_list
    #item 66
    set indent [ gen::make_indent $depth ]
    #item 67
    set body_depth [ expr { $depth + 1 } ]
    set lines [ gen::indent $body $body_depth ]
    #item 1800
    if {$name == "Shutdown"} {
        #item 1803
        set props(access) "public"
        set returns "void"
    } else {
        
    }
    #item 985
    set header ""
    #item 1074
    if {$props(access) == "none"} {
        
    } else {
        #item 995
        append header "$props(access) "
    }
    #item 1071
    if {$props(dispatch) == "normal"} {
        
    } else {
        #item 1007
        append header "$props(dispatch) "
    }
    #item 1011
    if {$type == "ctr"} {
        
    } else {
        #item 1014
        append header "$returns "
    }
    #item 1015
    append header "$name\("
    #item 1796
    if {$name == "Shutdown"} {
        #item 1799
        set params {}
    } else {
        #item 1623
        set params [ map2 $parameters gen_cs::take_first ]
        #item 1613
        if {[lindex $params 0 ] == "state machine"} {
            #item 1616
            set params [ lrange $params 1 end ]
        } else {
            
        }
    }
    #item 1021
    append header [ join $params ", " ]
    #item 1031
    append header "\)"
    #item 1036
    puts $fhandle ""
    #item 1033
    if {$props(dispatch) == "abstract"} {
        #item 1037
        puts $fhandle "$indent$header;"
    } else {
        #item 96
        puts $fhandle "$indent$header \{"
        #item 1804
        if {$name == "Shutdown"} {
            #item 1807
            puts $fhandle "$indent    if \(State == StateNames.Destroyed\) \{"
            puts $fhandle "$indent        return;"
            puts $fhandle "$indent    \}"
            puts $fhandle "$indent    State = StateNames.Destroyed;"
        } else {
            
        }
        #item 1808
        puts $fhandle $lines
        puts $fhandle "$indent\}"
    }
}

proc p.print_to_file { fhandle functions methods header class class_name footer machines } {
    #item 400
    set version [ version_string ]
    puts $fhandle \
        "// Autogenerated with DRAKON Editor $version"
    #item 68
    puts $fhandle $header
    #item 925
    puts $fhandle $class
    #item 1101
    print_machines $fhandle $machines
    #item 1247
    init_current_file $fhandle
    generate_data_struct $class_name $methods
    #item 926
    set ctrs      [ lfilter $functions gen_java::is_ctr ]
    set public    [ lfilter_user $functions gen_java::method_of_access "public"    ]
    set none      [ lfilter_user $functions gen_java::method_of_access "none"      ]
    set protected [ lfilter_user $functions gen_java::method_of_access "protected" ]
    set private   [ lfilter_user $functions gen_java::method_of_access "private"   ]
    set internal  [ lfilter_user $functions gen_java::method_of_access "internal"  ]
    #item 966
    print_procs 0 $fhandle $ctrs $class_name 1
    #item 967
    print_procs 0 $fhandle $public "" 1
    print_procs 0 $fhandle $internal "" 1
    print_procs 0 $fhandle $protected "" 1
    print_procs 0 $fhandle $private "" 1
    print_procs 0 $fhandle $none "" 1
    #item 1921
    if {$class_name == ""} {
        
    } else {
        #item 76
        puts $fhandle "\}"
    }
    #item 1068
    puts $fhandle $footer
}

proc parse_foreach { item_id init } {
    #item 1048
    set length [ llength $init ]
    #item 1050
    if {$length == 2} {
        
    } else {
        #item 1049
        set message "item id: $item_id, wrong syntax in foreach. Should be: Type variable; collection"
    }
    #item 1053
    return $init
}

proc print_bad { fhandle state method class_name } {
    #item 1160
    set message "\"$class_name: Method '$method' is not expected in state '$state'.\""
    #item 1161
    puts $fhandle "        throw new System.InvalidOperationException\($message\);"
    puts $fhandle "    \}"
}

proc print_good { fhandle state param_names } {
    #item 1153
    set arg_list [ join $param_names ", " ]
    set method "${state}_default"
    #item 1154
    puts $fhandle "        $method\($arg_list\);"
    puts $fhandle "    \}"
}

proc print_handler { fhandle states message params names handlers } {
    #item 1556
    puts $fhandle ""
    #item 1554
    puts $fhandle "        public object $message\($params\) \{"
    #item 1736
    handle_message $fhandle "" $states $message $names $handlers
    #item 1718
    puts $fhandle "        \}"
}

proc print_header { fhandle state message parameters } {
    #item 1147
    set arg_list [ join $parameters ", " ]
    #item 1146
    puts $fhandle "    private object ${state}_${message}\($arg_list\)"
    puts $fhandle "    \{"
}

proc print_machine { fhandle machine } {
    #item 1116
    if {$machine == {}} {
        
    } else {
        #item 1120
        set parameters [ dict get $machine "parameters" ]
        set param_names [ dict get $machine "param_names" ]
        set last [ dict get $machine "last" ]
        set boiler [ dict get $machine "boiler" ]
        set messages [ dict get $machine "messages" ]
        set states [ dict get $machine "states" ]
        set name [ dict get $machine "name" ]
        set handlers [ dict get $machine "handlers" ]
        set comments [ dict get $machine "comments" ]
        set has_final [ dict get $machine "has_final" ]
        #item 1681
        set weak [ is_weak $machine ]
        #item 1877
        lassign \
        [extract_body $comments] \
        body inherits
        #item 1541
        puts $fhandle ""
        puts $fhandle "    public partial class $name"
        #item 1701
        set real_params [ lrange $parameters 1 end ]
        set params [ join $real_params ", " ]
        #item 1844
        set pnames [ lrange $param_names 1 end ]
        set pnames_str [ join $pnames ", " ]
        #item 1843
        set arg_name_list [ join $pnames ", " ]
        #item 1878
        if {$inherits == ""} {
            
        } else {
            #item 1711
            puts $fhandle "        : $inherits"
        }
        #item 1676
        puts $fhandle "    \{"
        puts $fhandle "        $body"
        #item 1848
        puts $fhandle ""
        #item 1632
        puts $fhandle "        public enum StateNames \{"
        puts $fhandle "            Destroyed,"
        #item 1635
        set enum [ join $states ",\n            " ]
        #item 1634
        puts $fhandle "            $enum"
        #item 1633
        puts $fhandle "        \}"
        #item 1637
        set first [ lindex $states 0 ]
        #item 1847
        puts $fhandle ""
        #item 1636
        puts $fhandle "        private StateNames _state = StateNames.$first;"
        puts $fhandle ""
        puts $fhandle "        public StateNames State \{"
        puts $fhandle "            get \{ return _state; \}"
        puts $fhandle "            internal set \{ _state = value; \}"
        puts $fhandle "        \}"
        #item 1846
        puts $fhandle ""
        #item 1881
        lassign \
        [get_message_constants $name $messages] \
        messages mconstants
        #item 1840
        set i 1
        foreach message $mconstants {
            #item 1916
            lassign $message name value
            #item 1839
            puts $fhandle \
              "        public const int ${name}Message = $value;"
            #item 1841
            incr i
        }
        #item 1845
        puts $fhandle ""
        #item 1833
        puts $fhandle "        public object OnMessage(int messageType, $params\) \{"
        #item 1738
        puts $fhandle "            switch \(messageType\) \{"
        foreach message $messages {
            #item 1740
            puts $fhandle "                case ${message}Message:"
            #item 1842
            puts $fhandle "                    return ${message}\($pnames_str\);"
        }
        #item 1739
        puts $fhandle "                default:"
        puts $fhandle "                    return null;"
        puts $fhandle "            \}"
        puts $fhandle "        \}"
        foreach message $messages {
            #item 1698
            print_handler $fhandle \
              $states $message $params $arg_name_list \
              $handlers
        }
    }
    foreach procedure $handlers {
        #item 1791
        lassign $procedure _ proc_name
        #item 1832
        set proc2 [ set_void_return $procedure ]
        #item 1784
        p.print_proc $weak $fhandle $proc2 "" 2
    }
    #item 1542
    puts $fhandle "    \}"
}

proc print_machines { fhandle machines } {
    foreach machine $machines {
        #item 1540
        print_machine $fhandle $machine
    }
}

proc print_procs { weak_signature fhandle procedures class_name depth } {
    foreach procedure $procedures {
        #item 965
        p.print_proc $weak_signature $fhandle $procedure $class_name $depth
    }
}

proc print_special_state_class { fhandle messages iface name parameters line } {
    #item 1238
    set lines {}
    set count [ llength $messages ]
    #item 12390001
    set i 0
    while { 1 } {
        #item 12390002
        if {$i < $count} {
            
        } else {
            break
        }
        #item 1241
        lappend lines $line
        #item 12390003
        incr i
    }
    #item 1242
    print_state_class $fhandle $messages $iface $name $parameters $lines
}

proc print_state_class { fhandle messages iface name parameters lines } {
    #item 1202
    set sname "${name}_State_Definition"
    puts $fhandle "    private class $sname : $iface \{"
    puts $fhandle "        public string Name \{ get \{ return \"$name\"; \} \}"
    #item 1221
    set i 0
    foreach message $messages {
        #item 1206
        puts $fhandle "        public void $message\($parameters\) \{"
        #item 1223
        set line [ lindex $lines $i ]
        #item 1207
        puts $fhandle "            $line"
        puts $fhandle "        \}"
        #item 1222
        incr i
    }
    #item 1203
    puts $fhandle "    \}"
    puts $fhandle "    public static readonly $iface ${name}_State = new $sname\(\);"
}

proc print_state_method { fhandle message parameters param_names iface } {
    #item 1217
    set all_arg_names [ linsert $param_names 0 "this" ]
    set arg_list [ join $all_arg_names ", " ]
    #item 1216
    puts $fhandle "    public void ${message}\($parameters\) \{"
    puts $fhandle "        $iface current = _state;"
    puts $fhandle "        _state = Intermediate_State;"
    puts $fhandle "        current.${message}\($arg_list\);"
    puts $fhandle "    \}"
}

proc separate_methods { gdb all_functions functions_name methods_name } {
    #item 1270
    upvar $functions_name functions
    upvar $methods_name methods
    #item 1275
    array set methods_by_class {}
    set functions {}
    foreach function $all_functions {
        #item 1274
        lassign $function diagram_id name signature body
        #item 1568
        if {[sma::is_from_machine $gdb $diagram_id]} {
            
        } else {
            #item 1273
            lassign \
            [try_parse_method_name $diagram_id $name] \
            class_name method_name is_method
            #item 1276
            if {$is_method} {
                #item 1279
                set class [ tab::find_class $class_name ]
                #item 1280
                if {$class == ""} {
                    #item 1284
                    gen::report_error $diagram_id {} \
                    "Unknown class: '$class_name'"
                } else {
                    #item 1286
                    if {[info exists methods_by_class($class)]} {
                        #item 1290
                        set class_methods $methods_by_class($class)
                    } else {
                        #item 1289
                        set class_methods {}
                    }
                    #item 1307
                    set function2 [ list \
                     $diagram_id $method_name $signature $body ]
                    #item 1285
                    lappend class_methods $function2
                    set methods_by_class($class) $class_methods
                }
            } else {
                #item 1291
                lappend functions $function
            }
        }
    }
    #item 1292
    set methods [ array get methods_by_class ]
}

proc set_void_return { procedure } {
    #item 1826
    lassign $procedure diagram_id name signature body
    #item 1827
    lassign $signature type prop_list parameters returns
    #item 1828
    set returns2 "object"
    #item 1830
    set signature2 [ list $type $prop_list $parameters $returns2 ]
    #item 1831
    return [ list $diagram_id $name $signature2 $body ]
}

proc shelf { primary secondary } {
    #item 1080
    return "$secondary = $primary;"
}

proc standard_color { keywords type text } {
    #item 13670001
    if {$type == "op"} {
        #item 1379
        return $colors::syntax_operator
    } else {
        #item 13670002
        if {$type == "number"} {
            #item 1378
            return $colors::syntax_number
        } else {
            #item 13670003
            if {($type == "token") && ([contains $keywords $text])} {
                #item 1479
                return $colors::syntax_keyword
            } else {
                #item 1380
                return $colors::syntax_identifier
            }
        }
    }
}

proc take_first { item } {
    #item 1622
    return [ lindex $item 0 ]
}

proc try_parse_method_name { diagram_id name } {
    #item 1298
    set parts [ split $name "." ]
    #item 1299
    if {[ llength $parts ] == 2} {
        #item 1302
        lassign $parts first second
        #item 1303
        if {($first == "") || ($second == "")} {
            #item 1305
            return [ list "" "" 0 ]
        } else {
            #item 1306
            return [ list $first $second 1 ]
        }
    } else {
        #item 1305
        return [ list "" "" 0 ]
    }
}

}
