///|
fn push_children_reverse(stack : Array[@dom.Node], node : @dom.Node) -> Unit {
  let mut index = node.children.length()
  while index > 0 {
    index -= 1
    stack.push(node.children[index])
  }
}

///|
fn find_elements_by_name(root : @dom.Node, name : String) -> Array[@dom.Node] {
  let found : Array[@dom.Node] = []
  let stack : Array[@dom.Node] = [root]
  while !stack.is_empty() {
    let node = stack.pop().unwrap()
    if node.kind == Element && node.name == name {
      found.push(node)
    }
    push_children_reverse(stack, node)
  }
  found
}

///|
fn find_first_element_by_name(root : @dom.Node, name : String) -> @dom.Node? {
  let stack : Array[@dom.Node] = [root]
  while !stack.is_empty() {
    let node = stack.pop().unwrap()
    if node.kind == Element && node.name == name {
      return Some(node)
    }
    push_children_reverse(stack, node)
  }
  None
}

///|
fn selected_option_in(options : Array[@dom.Node]) -> @dom.Node? {
  for option in options {
    if option.attrs.contains("selected") {
      return Some(option)
    }
  }
  options.get(0)
}

///|
fn append_cloned_children(source : @dom.Node, target : @dom.Node) -> Unit {
  for child in source.children {
    target.append_child(child.clone_node(deep=true))
  }
}

///|
fn populate_selectedcontent(root : @dom.Node) -> Unit {
  let selects = find_elements_by_name(root, "select")
  for select in selects {
    if find_first_element_by_name(select, "selectedcontent")
      is Some(selectedcontent) {
      let options = find_elements_by_name(select, "option")
      if selected_option_in(options) is Some(option) {
        append_cloned_children(option, selectedcontent)
      }
    }
  }
}