hunk.code_window: export default function() {
     const rootDir = join('src', 'app', 'Upper-Dir');
     createDir(rootDir);
     const componentDir = join(rootDir, 'test-component');
     const componentTwoDir = join(rootDir, 'test-component-two');
  
hunk.labels: keep keep keep replace replace keep keep keep
hunk.after_edit:   const upperDirs = join('non', 'existing', 'dir');
     const rootDir = join('src', 'app', upperDirs);
  
hunk.file_path: tests/e2e/tests/generate/component/component-path-case.ts
hunk.type: replace
file: import * as fs from 'fs';
  import {join} from 'path';
  import * as ts from 'typescript';
  
  import {TypeScriptFileRefactor} from './refactor';
  
  
  function _recursiveSymbolExportLookup(refactor: TypeScriptFileRefactor,
                                        symbolName: string,
                                        host: ts.CompilerHost,
                                        program: ts.Program): string | null {
    // Check this file.
    const hasSymbol = refactor.findAstNodes(null, ts.SyntaxKind.ClassDeclaration)
      .some((cd: ts.ClassDeclaration) => {
        return cd.name && cd.name.text == symbolName;
      });
    if (hasSymbol) {
      return refactor.fileName;
    }
  
    // We found the bootstrap variable, now we just need to get where it's imported.
    const exports = refactor.findAstNodes(null, ts.SyntaxKind.ExportDeclaration)
      .map(node => node as ts.ExportDeclaration);
  
    for (const decl of exports) {
      if (!decl.moduleSpecifier || decl.moduleSpecifier.kind !== ts.SyntaxKind.StringLiteral) {
        continue;
      }
  
      const modulePath = (decl.moduleSpecifier as ts.StringLiteral).text;
      const resolvedModule = ts.resolveModuleName(
        modulePath, refactor.fileName, program.getCompilerOptions(), host);
      if (!resolvedModule.resolvedModule || !resolvedModule.resolvedModule.resolvedFileName) {
        return null;
      }
  
      const module = resolvedModule.resolvedModule.resolvedFileName;
      if (!decl.exportClause) {
        const moduleRefactor = new TypeScriptFileRefactor(module, host, program);
        const maybeModule = _recursiveSymbolExportLookup(moduleRefactor, symbolName, host, program);
        if (maybeModule) {
          return maybeModule;
        }
        continue;
      }
  
      const binding = decl.exportClause as ts.NamedExports;
      for (const specifier of binding.elements) {
        if (specifier.name.text == symbolName) {
          // If it's a directory, load its index and recursively lookup.
          if (fs.statSync(module).isDirectory()) {
            const indexModule = join(module, 'index.ts');
            if (fs.existsSync(indexModule)) {
              const indexRefactor = new TypeScriptFileRefactor(indexModule, host, program);
              const maybeModule = _recursiveSymbolExportLookup(
                indexRefactor, symbolName, host, program);
              if (maybeModule) {
                return maybeModule;
              }
            }
          }
  
          // Create the source and verify that the symbol is at least a class.
          const source = new TypeScriptFileRefactor(module, host, program);
          const hasSymbol = source.findAstNodes(null, ts.SyntaxKind.ClassDeclaration)
            .some((cd: ts.ClassDeclaration) => {
              return cd.name && cd.name.text == symbolName;
            });
  
          if (hasSymbol) {
            return module;
          }
        }
      }
    }
  
    return null;
  }
  
  function _symbolImportLookup(refactor: TypeScriptFileRefactor,
                               symbolName: string,
                               host: ts.CompilerHost,
                               program: ts.Program): string | null {
    // We found the bootstrap variable, now we just need to get where it's imported.
    const imports = refactor.findAstNodes(null, ts.SyntaxKind.ImportDeclaration)
      .map(node => node as ts.ImportDeclaration);
  
    for (const decl of imports) {
      if (!decl.importClause || !decl.moduleSpecifier) {
        continue;
      }
      if (decl.moduleSpecifier.kind !== ts.SyntaxKind.StringLiteral) {
        continue;
      }
  
      const resolvedModule = ts.resolveModuleName(
        (decl.moduleSpecifier as ts.StringLiteral).text,
        refactor.fileName, program.getCompilerOptions(), host);
      if (!resolvedModule.resolvedModule || !resolvedModule.resolvedModule.resolvedFileName) {
        return null;
      }
  
      const module = resolvedModule.resolvedModule.resolvedFileName;
      if (decl.importClause.namedBindings.kind == ts.SyntaxKind.NamespaceImport) {
        const binding = decl.importClause.namedBindings as ts.NamespaceImport;
        if (binding.name.text == symbolName) {
          // This is a default export.
          return module;
        }
      } else if (decl.importClause.namedBindings.kind == ts.SyntaxKind.NamedImports) {
        const binding = decl.importClause.namedBindings as ts.NamedImports;
        for (const specifier of binding.elements) {
          if (specifier.name.text == symbolName) {
            // Create the source and recursively lookup the import.
            const source = new TypeScriptFileRefactor(module, host, program);
            const maybeModule = _recursiveSymbolExportLookup(source, symbolName, host, program);
            if (maybeModule) {
              return maybeModule;
            }
          }
        }
      }
    }
    return null;
  }
  
  
  export function resolveEntryModuleFromMain(mainPath: string,
                                             host: ts.CompilerHost,
                                             program: ts.Program) {
    const source = new TypeScriptFileRefactor(mainPath, host, program);
  
    const bootstrap = source.findAstNodes(source.sourceFile, ts.SyntaxKind.CallExpression, true)
      .map(node => node as ts.CallExpression)
      .filter(call => {
        const access = call.expression as ts.PropertyAccessExpression;
        return access.kind == ts.SyntaxKind.PropertyAccessExpression
            && access.name.kind == ts.SyntaxKind.Identifier
            && (access.name.text == 'bootstrapModule'
                || access.name.text == 'bootstrapModuleFactory');
      })
      .map(node => node.arguments[0] as ts.Identifier)
      .filter(node => node.kind == ts.SyntaxKind.Identifier);
  
    if (bootstrap.length != 1) {
      throw new Error('Tried to find bootstrap code, but could not. Specify either '
        + 'statically analyzable bootstrap code or pass in an entryModule '
        + 'to the plugins options.');
    }
    const bootstrapSymbolName = bootstrap[0].text;
    const module = _symbolImportLookup(source, bootstrapSymbolName, host, program);
    if (module) {
      return `${module.replace(/\.ts$/, '')}#${bootstrapSymbolName}`;
    }
  
    // shrug... something bad happened and we couldn't find the import statement.
    throw new Error('Tried to find bootstrap code, but could not. Specify either '
      + 'statically analyzable bootstrap code or pass in an entryModule '
      + 'to the plugins options.');
  }
  