private static INaviCodeNode searchForSourceNodeOfEnterInlinedEdge(final INaviCodeNode node,final INaviFunction originalFunction,final Set<INaviCodeNode> visited){
  if (visited.contains(node)) {
    return null;
  }
  visited.add(node);
  for (  final INaviEdge incomingEdge : node.getIncomingEdges()) {
    if (incomingEdge.getType() == EdgeType.ENTER_INLINED_FUNCTION) {
      if (incomingEdge.getSource() instanceof INaviCodeNode) {
        return (INaviCodeNode)incomingEdge.getSource();
      }
 else {
        return null;
      }
    }
  }
  for (  final INaviEdge incomingEdge : node.getIncomingEdges()) {
    if (incomingEdge.getSource() instanceof INaviCodeNode) {
      final INaviCodeNode startNode=searchForSourceNodeOfEnterInlinedEdge((INaviCodeNode)incomingEdge.getSource(),originalFunction,visited);
      if (startNode != null) {
        return startNode;
      }
    }
  }
  return null;
}

private static INaviCodeNode searchForSourceNodeOfEnterInlinedEdge ( final INaviCodeNode node , final INaviFunction originalFunction , final Set < INaviCodeNode > visited ) { if ( visited . contains ( node ) ) { return null ; } visited . add ( node ) ; for ( final INaviEdge incomingEdge : node . getIncomingEdges ( ) ) { if ( incomingEdge . getType ( ) == EdgeType . ENTER_INLINED_FUNCTION ) { if ( incomingEdge . getSource ( ) instanceof INaviCodeNode ) { return ( INaviCodeNode ) incomingEdge . getSource ( ) ; } else { return null ; } } } for ( final INaviEdge incomingEdge : node . getIncomingEdges ( ) ) { if ( incomingEdge . getSource ( ) instanceof INaviCodeNode ) { final INaviCodeNode startNode = searchForSourceNodeOfEnterInlinedEdge ( ( INaviCodeNode ) incomingEdge . getSource ( ) , originalFunction , visited ) ; if ( startNode != null ) { return startNode ; } } } return null ; }
starting from the given node , this function iterates over all incoming edges of the node and checks if any of these edges is of type enter_inlined_function . if this is the case , it returns the source node of this edge . the purpose of this is to return the node " from which " the node under consideration was inlined . if none of the incoming edges of the current node are of the type enter_inlined_function , recurse into the parent nodes until we find the relevant node . this function may run out of java stack space on very deeply inlined flowgraphs ; we might wish to consider rewriting it in non - recursive . the function is also prone to break unpredictably in functions that have in - lined the same function multiple times and contain a loop . pretty much the entire uninline - logic needs to be rewritten eventually .
