protected void collectVariants(final List<Object> result) {
    int prefixLength = 0;
    if (myText.startsWith("pom.")) {
      prefixLength = "pom.".length();
    } else if (myText.startsWith("project.")) {
      prefixLength = "project.".length();
    }

    MavenProject mavenProject = myMavenProject;
    while (myText.startsWith("parent.", prefixLength)) {
      MavenId parentId = mavenProject.getParentId();
      if (parentId == null) return;

      mavenProject = myProjectsManager.findProject(parentId);
      if (mavenProject == null) return;

      prefixLength += "parent.".length();
    }

    final String prefix = prefixLength == 0 ? null : myText.substring(0, prefixLength);

    PsiDirectory baseDir = getBaseDir(mavenProject);
    addVariant(result, "basedir", baseDir, prefix, icons.MavenIcons.MavenLogo);
    if (prefix == null) {
      result.add(createLookupElement(baseDir, "project.baseUri", icons.MavenIcons.MavenLogo));
      result.add(createLookupElement(baseDir, "pom.baseUri", icons.MavenIcons.MavenLogo));
      result.add(LookupElementBuilder.create(TIMESTAMP_PROP).withIcon(icons.MavenIcons.MavenLogo));
    }

    processSchema(
        MavenSchemaProvider.MAVEN_PROJECT_SCHEMA_URL,
        new SchemaProcessor<Object>() {
          @Override
          public Object process(@NotNull String property, XmlElementDescriptor descriptor) {
            if (property.startsWith("project.")) {
              addVariant(
                  result,
                  property.substring("project.".length()),
                  descriptor,
                  prefix,
                  icons.MavenIcons.MavenLogo);
            }
            return null;
          }
        });

    processSchema(
        MavenSchemaProvider.MAVEN_SETTINGS_SCHEMA_URL,
        new SchemaProcessor<Object>() {
          @Override
          public Object process(@NotNull String property, XmlElementDescriptor descriptor) {
            result.add(createLookupElement(descriptor, property, icons.MavenIcons.MavenLogo));
            return null;
          }
        });

    collectPropertiesVariants(result);
    collectSystemEnvProperties(
        MavenPropertiesVirtualFileSystem.SYSTEM_PROPERTIES_FILE, null, result);
    collectSystemEnvProperties(
        MavenPropertiesVirtualFileSystem.ENV_PROPERTIES_FILE, "env.", result);

    MavenRunnerSettings runnerSettings = MavenRunner.getInstance(myProject).getSettings();
    for (String prop : runnerSettings.getMavenProperties().keySet()) {
      if (!isResultAlreadyContains(result, prop)) {
        result.add(LookupElementBuilder.create(prop).withIcon(PlatformIcons.PROPERTY_ICON));
      }
    }
    for (String prop : MavenUtil.getPropertiesFromMavenOpts().keySet()) {
      if (!isResultAlreadyContains(result, prop)) {
        result.add(LookupElementBuilder.create(prop).withIcon(PlatformIcons.PROPERTY_ICON));
      }
    }
  }
  // See
  // org.apache.maven.project.interpolation.AbstractStringBasedModelInterpolator.createValueSources()
  @Nullable
  protected PsiElement doResolve() {
    boolean hasPrefix = false;
    String unprefixed = myText;

    if (myText.startsWith("pom.")) {
      unprefixed = myText.substring("pom.".length());
      hasPrefix = true;
    } else if (myText.startsWith("project.")) {
      unprefixed = myText.substring("project.".length());
      hasPrefix = true;
    }

    MavenProject mavenProject = myMavenProject;

    while (unprefixed.startsWith("parent.")) {
      if (unprefixed.equals("parent.groupId")
          || unprefixed.equals("parent.artifactId")
          || unprefixed.equals("parent.version")
          || unprefixed.equals("parent.relativePath")) {
        break;
      }

      MavenId parentId = mavenProject.getParentId();
      if (parentId == null) return null;

      mavenProject = myProjectsManager.findProject(parentId);
      if (mavenProject == null) return null;

      unprefixed = unprefixed.substring("parent.".length());
    }

    if (unprefixed.equals("basedir")
        || (hasPrefix && mavenProject == myMavenProject && unprefixed.equals("baseUri"))) {
      return getBaseDir(mavenProject);
    }

    if (myText.equals(TIMESTAMP_PROP)) {
      return myElement;
    }

    if (hasPrefix) {
      MavenDomProjectModel domProjectModel =
          MavenDomUtil.getMavenDomProjectModel(myProject, mavenProject.getFile());
      if (domProjectModel != null) {
        PsiElement res =
            resolveModelProperty(domProjectModel, unprefixed, new HashSet<DomElement>());
        if (res != null) {
          return res;
        }
      }
    }

    // todo resolve properties from config.
    MavenRunnerSettings runnerSettings = MavenRunner.getInstance(myProject).getSettings();
    if (runnerSettings.getMavenProperties().containsKey(myText)
        || runnerSettings.getVmOptions().contains("-D" + myText + '=')) {
      return myElement;
    }
    if (MavenUtil.getPropertiesFromMavenOpts().containsKey(myText)) {
      return myElement;
    }

    MavenDomProfile profile = DomUtil.findDomElement(myElement, MavenDomProfile.class);
    if (profile != null) {
      PsiElement result =
          MavenDomProjectProcessorUtils.findProperty(profile.getProperties(), myText);
      if (result != null) return result;
    }

    if (myProjectDom != null) {
      PsiElement result =
          MavenDomProjectProcessorUtils.searchProperty(myText, myProjectDom, myProject);
      if (result != null) return result;
    }

    MavenPropertiesVirtualFileSystem mavenPropertiesVirtualFileSystem =
        MavenPropertiesVirtualFileSystem.getInstance();

    IProperty property = mavenPropertiesVirtualFileSystem.findSystemProperty(myProject, myText);
    if (property != null) return property.getPsiElement();

    if (myText.startsWith("env.")) {
      property =
          mavenPropertiesVirtualFileSystem.findEnvProperty(
              myProject, myText.substring("env.".length()));
      if (property != null) return property.getPsiElement();
    }

    String textWithEnv = "env." + myText;

    property = mavenPropertiesVirtualFileSystem.findSystemProperty(myProject, textWithEnv);
    if (property != null) return property.getPsiElement();

    property = mavenPropertiesVirtualFileSystem.findEnvProperty(myProject, textWithEnv);
    if (property != null) return property.getPsiElement();

    if (!hasPrefix) {
      MavenDomProjectModel domProjectModel =
          MavenDomUtil.getMavenDomProjectModel(myProject, mavenProject.getFile());
      if (domProjectModel != null) {
        PsiElement res =
            resolveModelProperty(domProjectModel, unprefixed, new HashSet<DomElement>());
        if (res != null) {
          return res;
        }
      }
    }

    if (myText.startsWith("settings.")) {
      return resolveSettingsModelProperty();
    }

    return null;
  }