## -*-octave-*-

function [bonds,components,n_vector_bonds] = ibg2abg(name,bonds, \
						     infofile, \
						     errorfile)

  ## Provide useful data for log
  struct_levels_to_print = 5;

  ## Find number of bonds
  [n_bonds, junk] = size(struct_elements(bonds));

  ## Get components
  max_bonds_on_component = 0;

  for i = 1:n_bonds
    eval(sprintf("bond = bonds.b%i", i));

    ## heads
    head_type_name = bond.head.component;
    head_type_name = deblank(split(head_type_name, ":"));
    head_type = head_type_name(1,:);
    head_name = head_type_name(2,:);
    if (exist("component_struct"))
      if (struct_contains(component_struct, head_name))
	## create a copy to work on - clearer than eval(sprintf(...))
	## (pointers would be better still!)
	eval(sprintf("head = component_struct.%s;", head_name));
      endif
    endif
    head.type = head_type;
    if (!struct_contains(head,"bonds"))
      head.n_bonds = 1;
      head.bonds = [+i];
      head.named_ports = !strcmp(bond.head.ports, "[]");
    else
      head.n_bonds = head.n_bonds + 1;
      head.bonds = [head.bonds, +i];
      head.named_ports = head.named_ports + !strcmp(bond.head.ports, \
						    "[]");
    endif
    eval(sprintf("head.ports.bond%i.name = '%s'", i, bond.head.ports));
    eval(sprintf("head.ports.bond%i.sign = '[in]'", i));
    max_bonds_on_component = max(max_bonds_on_component, \
				 head.n_bonds)
    eval(sprintf("component_struct.%s = head", head_name));
    clear head;

    ## tails
    tail_type_name = bond.tail.component;
    tail_type_name = deblank(split(tail_type_name, ":"));
    tail_type = tail_type_name(1,:);
    tail_name = tail_type_name(2,:);
    if (exist("component_struct"))
      if (struct_contains(component_struct, tail_name))
	## create a copy to work on - clearer than eval(sprintf(...))
	tail = eval(sprintf("tail = component_struct.%s", tail_name));
      endif
    endif
    tail.type = tail_type;
    if (!struct_contains(tail,"bonds"))
      tail.n_bonds = 1;
      tail.bonds = [-i];
      tail.named_ports = !strcmp(bond.tail.ports, "[]");
    else
      tail.n_bonds = tail.n_bonds + 1
      tail.bonds = [tail.bonds, -i];
      tail.named_ports = tail.named_ports + !strcmp(bond.tail.ports, \
						    "[]");
    endif
    eval(sprintf("tail.ports.bond%i.name = '%s'", i, bond.tail.ports));
    eval(sprintf("tail.ports.bond%i.sign = '[out]'", i));
    max_bonds_on_component = max(max_bonds_on_component, \
				 tail.n_bonds);
    eval(sprintf("component_struct.%s = tail", tail_name));
    clear tail;

  endfor
  
  ## Get component indices from sys_cmp.m
  [n_components, junk] = size(struct_elements(component_struct));
  for i = 1:n_components
    [comp_type, comp_name] = eval(sprintf("%s_cmp(%i)", name, i));
    eval(sprintf("component_struct.%s.index = %i", comp_name, i));
  endfor

  ## Create the connections matrix (components)
  components = zeros(n_components, max_bonds_on_component);
  for [comp, comp_name] = component_struct
    components(comp.index,1:comp.n_bonds) = comp.bonds;
  endfor
  
  for [comp, comp_name] = component_struct
    ## Unalias and/or default all ports on this component
    if ((strcmp(deblank(comp.type), "0")) || (strcmp(deblank(comp.type), "1")))
      disp("---- default junctions ----");
      if (comp.named_ports == 1) # one named port
	for [port, bond_number] = comp.ports
	  if (!strcmp(port.name,"[]"))
	    junction_port_name = port.name;
	  endif
	endfor
	mtt_info(sprintf("Defaulting all ports on junction %s to %s", \
			 comp_name, junction_port_name));
	for [port, bond_number] = comp.ports
	  port.name = junction_port_name;
	endfor	
      elseif ((comp.named_ports != 0) && (comp.named_ports != \
					  comp.n_bonds)) # not allowed
	mtt_error(sprintf("Junction %s must have 0, 1 or %i port labels", \
			  comp_name, comp.n_bonds));
      endif
    else			# Not a junction
      unlabelled_ports = comp.n_bonds - comp.named_ports;
      if (unlabelled_ports == 1)
	## find unlabelled ports
	for [port, bond_number] = comp.ports
	  if (strcmp(deblank(port.name), "[]"))
	    ## found it - default to "in" or "out"
	    eval(sprintf("comp.ports.%s.name = port.sign", bond_number));
	    mtt_info(["Defaulting port name [" port.sign "]\t on component " \
		      comp_name " (" deblank(comp.type) ")"], infofile);
	  endif
	endfor
      elseif (unlabelled_ports == 2)
	## find unlabelled ports
	for [port, bond_number] = comp.ports
	  if (strcmp(deblank(port.name), "[]"))
	    ## got one
	    if (exist("unlabelled_port1"))
	      unlabelled_port2 = port;
	      bond_number2 = bond_number;
	    else
	      unlabelled_port1 = port;
	      bond_number1 = bond_number;
	    endif
	  endif
	endfor
	if (strcmp(unlabelled_port1.sign, "[in]") && \
	    strcmp(unlabelled_port2.sign, "[in]"))
	  mtt_error(["More than one unlabelled INport on component " \
		     comp_name " (" deblank(comp.type) ")"], errorfile);
	elseif (strcmp(unlabelled_port1.sign, "[out]") && \
		strcmp(unlabelled_port2.sign, "[out]"))
	  mtt_error(["More than one unlabelled OUTport on component " \
		     comp_name " (" deblank(comp.type) ")"], errorfile);
	else
	  eval(sprintf("comp.ports.%s.name = \
	  unlabelled_port1.sign", bond_number1));
	  mtt_info(["Defaulting port name [" unlabelled_port1.sign
		    "]\t on component "  comp_name " (" \
		    deblank(comp.type) ")"], infofile);
	  eval(sprintf("comp.ports.%s.name = \
	  unlabelled_port2.sign", bond_number2));
	  mtt_info(["Defaulting port name [" unlabelled_port2.sign
		    "]\t on component "  comp_name " (" \
		    deblank(comp.type) ")"], infofile);
	endif
	## ???	
      endif
    ## ???	
    endif
    ## ???
    eval(sprintf("component_struct.%s = comp", comp_name));    
  endfor
component_struct;
  ## ???
  bonds;
  components;
  n_vector_bonds = 1;
endfunction