/**
   * Checks that unacceptable property value prevents SPI from being started.
   *
   * @param spi Spi to test property on.
   * @param propName name of property to check.
   * @param val An illegal value.
   * @param checkExMsg If {@code true} then additional info will be added to failure.
   * @throws Exception If check failed.
   */
  protected void checkNegativeSpiProperty(
      IgniteSpi spi, String propName, Object val, boolean checkExMsg) throws Exception {
    assert spi != null;
    assert propName != null;

    getTestData().getTestResources().inject(spi);

    String mtdName = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);

    Method mtd = null;

    for (Method m : spi.getClass().getMethods())
      if (m.getName().equals(mtdName)) {
        mtd = m;

        break;
      }

    assert mtd != null : "The setter is not found for property: " + propName;

    boolean err = false;

    try {
      mtd.invoke(spi, val);
    } catch (InvocationTargetException e) {
      info("SPI property setter thrown exception: " + e);

      if (e.getCause() instanceof IllegalArgumentException) err = true;
      else throw e;
    }

    if (!err)
      try {
        if (!(spi instanceof DiscoverySpi)) spi.getNodeAttributes();

        spi.spiStart(getTestGridName());
      } catch (IgniteSpiException e) {
        info("SPI start thrown exception: " + e);

        if (checkExMsg)
          assert e.getMessage().contains("SPI parameter failed condition check: ")
              : "SPI has returned wrong exception message [propName="
                  + propName
                  + ", msg="
                  + e
                  + ']';

        err = true;
      }

    assert err : "No check for property [property=" + propName + ", value=" + val + ']';
  }
  /** {@inheritDoc} */
  @Override
  public void start() throws GridException {
    if (ctx.isEnterprise()) {
      Package pkg = getClass().getPackage();

      if (pkg == null)
        throw new GridException(
            "Internal error (package object was not found) for: " + getClass().getName());

      if (ctx.isEnterprise()) {
        try {
          Class<?> cls = Class.forName(pkg.getName() + ".GridEnterpriseSecureSessionHandler");

          sesHnd =
              (GridSecureSessionHandler)
                  cls.getConstructor(GridSecureSessionSpi[].class)
                      .newInstance(new Object[] {getProxies()});
        } catch (ClassNotFoundException e) {
          throw new GridException(
              "Failed to create enterprise secure session handler (implementing class "
                  + "was not found)",
              e);
        } catch (InvocationTargetException e) {
          throw new GridException(
              "Failed to create enterprise secure session handler (target constructor "
                  + "has thrown an exception",
              e.getCause());
        } catch (InstantiationException e) {
          throw new GridException(
              "Failed to create enterprise secure session handler (object cannot be "
                  + "instantiated)",
              e);
        } catch (NoSuchMethodException e) {
          throw new GridException(
              "Failed to create enterprise secure session handler (target constructor "
                  + "could not be found)",
              e);
        } catch (IllegalAccessException e) {
          throw new GridException(
              "Failed to create enterprise secure session handler (object access is not"
                  + " allowed)",
              e);
        }
      }
    } else sesHnd = new GridCommunitySecureSessionHandler();

    startSpi();

    if (log.isDebugEnabled()) log.debug(startInfo());
  }