public void searchOrDownloadPlugin(
      final String packageName, final int type, final boolean search) {
    logger.info("searchOrDownloadPlugin: " + packageName + ", search: " + search);

    Tracker.initializeTracking(getBaseContext(), packageName, type, search);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    if (search) intent.setData(Uri.parse("market://search?q=" + packageName));
    else intent.setData(Uri.parse("market://details?id=" + packageName));

    try {
      getBaseContext().startActivity(intent);
    } catch (ActivityNotFoundException e) {
      Toast.makeText(getBaseContext(), R.string.feather_activity_not_found, Toast.LENGTH_SHORT)
          .show();
      e.printStackTrace();
    }
  }
  /**
   * This is the entry point of every feather tools. The main activity catches the tool onClick
   * listener and notify the filtermanager.
   *
   * @param tag the tag
   */
  public void activateEffect(final EffectEntry tag) {
    if (!getEnabled() || !isClosed() || mBitmap == null) return;

    if (mCurrentEffect != null)
      throw new IllegalStateException("There is already an active effect. Cannot activate new");
    if (mEffectLoader == null)
      mEffectLoader = (EffectLoaderService) getService(EffectLoaderService.class);

    final AbstractEffectPanel effect = mEffectLoader.load(tag);

    if (effect != null) {
      mCurrentEffect = effect;
      mCurrentEntry = tag;

      setCurrentState(STATE.OPENING);
      prepareEffectPanel(effect, tag);

      Tracker.recordTag(mCurrentEntry.name.name().toLowerCase(Locale.US) + ": opened");
      mContext
          .getBottomBar()
          .setOnPanelOpenListener(
              new OnPanelOpenListener() {

                @Override
                public void onOpened() {
                  setCurrentState(STATE.OPENED);
                  mContext.getBottomBar().setOnPanelOpenListener(null);
                }

                @Override
                public void onOpening() {
                  mCurrentEffect.onOpening();
                }
              });

      mContext.getBottomBar().open();
    }
  }
  public void searchOrDownloadPlugin(
      final String packageName, final int type, final boolean search) {
    logger.info("searchOrDownloadPlugin: " + packageName + ", search: " + search);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    if (search) intent.setData(Uri.parse("market://search?q=" + packageName));
    else intent.setData(Uri.parse("market://details?id=" + packageName));

    try {

      String name = FeatherIntent.PluginType.getName(type);
      if (null != name) {
        HashMap<String, String> attrs = new HashMap<String, String>();
        attrs.put("assetType", name);
        Tracker.recordTag("content: addMoreClicked", attrs);
      }
      getBaseContext().startActivity(intent);
    } catch (ActivityNotFoundException e) {
      Toast.makeText(getBaseContext(), R.string.feather_activity_not_found, Toast.LENGTH_SHORT)
          .show();
      e.printStackTrace();
    }
  }
  @Override
  public void onComplete(
      final Bitmap result, MoaActionList actions, HashMap<String, String> trackingAttributes) {
    logger.info("onComplete: " + android.os.Debug.getNativeHeapAllocatedSize());
    Tracker.recordTag(
        mCurrentEntry.name.name().toLowerCase(Locale.US) + ": applied", trackingAttributes);

    if (result != null) {
      if (mCurrentEffect instanceof ContentPanel) {
        ContentPanel panel = (ContentPanel) mCurrentEffect;
        final boolean changed = BitmapUtils.compareBySize(mBitmap, result);
        setNextBitmap(result, true, changed ? null : panel.getContentDisplayMatrix());
      } else {
        setNextBitmap(result, false);
      }

    } else {
      logger.error("Error: returned bitmap is null!");
      setNextBitmap(mBitmap, true);
    }

    onClose(true);

    if (mHiResEnabled) {
      // send the actions...
      if (null == actions) logger.error("WTF actionlist is null!!!!");

      HiResService service = getService(HiResService.class);
      if (service.isRunning()) {
        service.execute(mSessionId, mApiKey, actions);
      }
    }

    if (null != mHiResListener) {
      mHiResListener.OnApplyActions(actions);
    }
  }
  @Override
  public void cancel() {

    logger.info("FilterManager::cancel");

    if (!getEnabled() || !isOpened()) return;
    if (mCurrentEffect == null)
      throw new IllegalStateException("there is no current effect active in the context");

    Tracker.recordTag(mCurrentEntry.name.name().toLowerCase(Locale.US) + ": cancelled");

    // send the cancel event to the effect
    mCurrentEffect.onCancelled();

    // check changed image
    if (mCurrentEffect.getIsChanged()) {
      // panel is changed, restore the original bitmap

      if (mCurrentEffect instanceof ContentPanel) {
        ContentPanel panel = (ContentPanel) mCurrentEffect;
        setNextBitmap(mBitmap, true, panel.getContentDisplayMatrix());
      } else {
        setNextBitmap(mBitmap, false);
      }

    } else {
      // panel is not changed
      if (mCurrentEffect instanceof ContentPanel) {
        ContentPanel panel = (ContentPanel) mCurrentEffect;
        setNextBitmap(mBitmap, true, panel.getContentDisplayMatrix());
      } else {
        setNextBitmap(mBitmap, false);
      }
    }
    onClose(false);
  }