@Override
  public String from(final IProject project) {
    final ProjectManager projectManager = projectManagerSupplier.get();

    final IPath projectPath = project.getLocation();
    final IPath substepsPath = projectManager.substepsFolderFor(project);

    if (!projectPath.isPrefixOf(substepsPath)) {
      return null;
    }
    return substepsPath.toOSString().substring(projectPath.toOSString().length() + 1);
  }
  @Override
  public Syntax from(final IProject project) {

    if (SubstepsNature.isSubstepsProject(project)) {
      final IJavaProject javaProject = new ProjectToJavaProjectTransformer().from(project);
      if (javaProject != null) {
        final ClassLoader classLoader = new JavaProjectClassLoader(javaProject);
        final Set<String> outputFolders = outputFoldersForProject(javaProject);
        final File substepsFolder =
            new File(projectManager.substepsFolderFor(project).toOSString());

        final List<Class<?>> stepClasses = new ArrayList<Class<?>>();
        for (final String outputFolder : outputFolders) {
          final ClassLocator classLocator = new StepClassLocator(outputFolder, classLoader);
          stepClasses.addAll(stepClasses(outputFolder, classLocator));
        }
        // augment step classes with externally dependent classes
        stepClasses.addAll(externalDependenciesFor(project, classLoader));

        try {
          return buildSyntaxFor(
              project, substepsFolder, stepClasses, classLoader, syntaxErrorReporterFor(project));
        } catch (final RuntimeException ex) {
          FeatureEditorPlugin.instance()
              .warn(
                  "Error when building syntax for project " + project + ": " + ex.getMessage(), ex);
        }
      }
    }
    // If we get to here, we can't resolve a valid syntax, return a null one
    final Syntax nullSyntax = new Syntax();
    nullSyntax.setSubStepsMap(new PatternMap<ParentStep>());
    return nullSyntax;
  }