private static AbstractTypeDeclaration getTypeNode(
      CompilationUnitEditor targetCompilationUnitEditor) {
    IWorkingCopyManager manager =
        JavaPlugin.getDefault().getWorkingCopyManager();
    ICompilationUnit compilationUnit =
        manager.getWorkingCopy(targetCompilationUnitEditor.getEditorInput());
    CompilationUnit root =
        JavaPlugin.getDefault().getASTProvider().getAST(compilationUnit,
            ASTProvider.WAIT_YES, null);

    Point selectedRange = getPosition(targetCompilationUnitEditor);
    NodeFinder finder = new NodeFinder(selectedRange.x, selectedRange.y);
    root.accept(finder);
    ASTNode node = finder.getCoveringNode();
    ASTNode nameNode =
        NodeFinder.perform(root, node.getStartPosition(), node.getLength());
    while (true) {
      
      if (node instanceof TypeDeclaration) {
        TypeDeclaration temp = (TypeDeclaration)node;
        // this is an interface, keep on going
        if (!temp.isInterface()) {
          break;
        }
      }
      if (node instanceof EnumDeclaration) {
        //TODO: enums need non-public constructors
        break;
      }
      
      node = node.getParent();
      if (node == null) {
        // TODO: better error handling -- this is not applicable to this file/selection
        throw new RuntimeException("Not applicable");
      }
    }
    AbstractTypeDeclaration typeNode = (AbstractTypeDeclaration) node;
    
    return typeNode;
  }