// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util;

import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionNotApplicableException;
import com.intellij.openapi.extensions.PluginDescriptor;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProcessCanceledException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;

public final class ExtensionInstantiator {
  private static final Logger LOG = Logger.getInstance(ExtensionInstantiator.class);

  private ExtensionInstantiator() {
  }

  @NotNull
  public static <T> T instantiateWithPicoContainerOnlyIfNeeded(@Nullable String className,
                                                               @NotNull PicoContainer picoContainer,
                                                               @Nullable PluginDescriptor pluginDescriptor) {
    PluginId pluginId = pluginDescriptor == null ? null : pluginDescriptor.getPluginId();
    if (className == null) {
      throw new PluginException("implementation class is not specified", pluginId);
    }

    Class<T> clazz;
    try {
      clazz = AbstractExtensionPointBean.findClass(className, pluginDescriptor);
    }
    catch (ClassNotFoundException e) {
      throw new PluginException(e, pluginId);
    }

    try {
      return ReflectionUtil.newInstance(clazz, false);
    }
    catch (ProcessCanceledException | ExtensionNotApplicableException e) {
      throw e;
    }
    catch (Throwable e) {
      if (e.getCause() instanceof NoSuchMethodException) {
        PluginException exception = new PluginException("Bean extension class constructor must not have parameters: " + className, pluginId);
        Application app = ApplicationManager.getApplication();
        if (app != null && app.isUnitTestMode()) {
          LOG.error(exception);
        }
        else {
          LOG.warn(exception);
        }
      }
      else {
        throw new PluginException(e, pluginId);
      }
    }

    try {
      return AbstractExtensionPointBean.instantiate(clazz, picoContainer, true);
    }
    catch (ProcessCanceledException e) {
      throw e;
    }
    catch (Throwable e) {
      throw new PluginException(e, pluginId);
    }
  }
}

@@ -166,56 +166,8 @@
 l;%0A%0A
-import com.intellij.diagnostic.PluginException;%0A
 impo
@@ -365,212 +365,9 @@
 ons.
-AbstractExtensionPointBean;%0Aimport com.intellij.openapi.extensions.ExtensionNotApplicableException;%0Aimport com.intellij.openapi.extensions.PluginDescriptor;%0Aimport com.intellij.openapi.extensions.PluginId
+*
 ;%0Aim
@@ -1040,98 +1040,8 @@
 ) %7B%0A
-    PluginId pluginId = pluginDescriptor == null ? null : pluginDescriptor.getPluginId();%0A
     
@@ -1073,37 +1073,53 @@
       throw new 
-Plugi
+ExtensionInstantiatio
 nException(%22impl
@@ -1152,34 +1152,42 @@
 ecified%22, plugin
-Id
+Descriptor
 );%0A    %7D%0A%0A    Cl
@@ -1344,37 +1344,53 @@
       throw new 
-Plugi
+ExtensionInstantiatio
 nException(e, pl
@@ -1385,34 +1385,42 @@
 eption(e, plugin
-Id
+Descriptor
 );%0A    %7D%0A%0A    tr
@@ -1673,22 +1673,16 @@
         
-Plugin
 Exceptio
@@ -1695,29 +1695,45 @@
 ption = new 
-Plugi
+ExtensionInstantiatio
 nException(%22
@@ -1804,34 +1804,42 @@
 lassName, plugin
-Id
+Descriptor
 );%0A        Appli
@@ -2068,37 +2068,53 @@
       throw new 
-Plugi
+ExtensionInstantiatio
 nException(e, pl
@@ -2113,26 +2113,34 @@
 on(e, plugin
-Id
+Descriptor
 );%0A      %7D%0A 
@@ -2346,21 +2346,37 @@
 row new 
-Plugi
+ExtensionInstantiatio
 nExcepti
@@ -2391,10 +2391,18 @@
 ugin
-Id
+Descriptor
 );%0A 

use ExtensionInstantiationException in ExtensionInstantiator for consistency