@Override
  public void createOrUpdateView(String path, String config, boolean ignoreExisting) {
    validateUpdateArgs(path, config);
    String viewBaseName = FilenameUtils.getName(path);
    Jenkins.checkGoodName(viewBaseName);
    try {
      InputStream inputStream = new ByteArrayInputStream(config.getBytes("UTF-8"));

      ItemGroup parent = lookupStrategy.getParent(build.getProject(), path);
      if (parent instanceof ViewGroup) {
        View view = ((ViewGroup) parent).getView(viewBaseName);
        if (view == null) {
          if (parent instanceof Jenkins) {
            ((Jenkins) parent).addView(createViewFromXML(viewBaseName, inputStream));
          } else if (parent instanceof Folder) {
            ((Folder) parent).addView(createViewFromXML(viewBaseName, inputStream));
          } else {
            LOGGER.log(Level.WARNING, format("Could not create view within %s", parent.getClass()));
          }
        } else if (!ignoreExisting) {
          view.updateByXml(new StreamSource(inputStream));
        }
      } else if (parent == null) {
        throw new DslException(format(Messages.CreateView_UnknownParent(), path));
      } else {
        LOGGER.log(Level.WARNING, format("Could not create view within %s", parent.getClass()));
      }
    } catch (UnsupportedEncodingException e) {
      LOGGER.log(Level.WARNING, "Unsupported encoding used in config. Should be UTF-8.");
    } catch (IOException e) {
      e.printStackTrace();
      LOGGER.log(Level.WARNING, format("Error writing config for new view %s.", path), e);
    }
  }
  private void updateGeneratedViews(
      AbstractBuild<?, ?> build, BuildListener listener, Set<GeneratedView> freshViews)
      throws IOException {
    Set<GeneratedView> generatedViews =
        extractGeneratedObjects(build.getProject(), GeneratedViewsAction.class);
    Set<GeneratedView> added = Sets.difference(freshViews, generatedViews);
    Set<GeneratedView> existing = Sets.intersection(generatedViews, freshViews);
    Set<GeneratedView> removed = Sets.difference(generatedViews, freshViews);

    logItems(listener, "Adding views", added);
    logItems(listener, "Existing views", existing);
    logItems(listener, "Removing views", removed);

    // Delete views
    if (removedViewAction == RemovedViewAction.DELETE) {
      for (GeneratedView removedView : removed) {
        String viewName = removedView.getName();
        ItemGroup parent = getLookupStrategy().getParent(build.getProject(), viewName);
        if (parent instanceof ViewGroup) {
          View view = ((ViewGroup) parent).getView(FilenameUtils.getName(viewName));
          if (view != null) {
            ((ViewGroup) parent).deleteView(view);
          }
        } else if (parent == null) {
          LOGGER.log(Level.FINE, "Parent ViewGroup seems to have been already deleted");
        } else {
          LOGGER.log(Level.WARNING, format("Could not delete view within %s", parent.getClass()));
        }
      }
    }
  }
  private void renameJob(Job from, String to) throws IOException {
    LOGGER.info(format("Renaming job %s to %s", from.getFullName(), to));

    ItemGroup fromParent = from.getParent();
    ItemGroup toParent = lookupStrategy.getParent(build.getProject(), to);
    if (fromParent != toParent) {
      LOGGER.info(
          format("Moving Job %s to folder %s", fromParent.getFullName(), toParent.getFullName()));
      if (toParent instanceof DirectlyModifiableTopLevelItemGroup) {
        DirectlyModifiableTopLevelItemGroup itemGroup =
            (DirectlyModifiableTopLevelItemGroup) toParent;
        move(from, itemGroup);
      } else {
        throw new DslException(
            format(
                Messages.RenameJobMatching_DestinationNotFolder(),
                from.getFullName(),
                toParent.getFullName()));
      }
    }
    from.renameTo(FilenameUtils.getName(to));
  }
  private boolean createNewItem(String path, String config) {
    LOGGER.log(Level.FINE, format("Creating item as %s", config));
    boolean created = false;

    try {
      InputStream is = new ByteArrayInputStream(config.getBytes("UTF-8"));

      ItemGroup parent = lookupStrategy.getParent(build.getProject(), path);
      String itemName = FilenameUtils.getName(path);
      if (parent instanceof ModifiableTopLevelItemGroup) {
        ((ModifiableTopLevelItemGroup) parent).createProjectFromXML(itemName, is);
        created = true;
      } else if (parent == null) {
        throw new DslException(format(Messages.CreateItem_UnknownParent(), path));
      } else {
        LOGGER.log(Level.WARNING, format("Could not create item within %s", parent.getClass()));
      }
    } catch (UnsupportedEncodingException e) {
      LOGGER.log(Level.WARNING, "Unsupported encoding used in config. Should be UTF-8.");
    } catch (IOException e) {
      LOGGER.log(Level.WARNING, format("Error writing config for new item %s.", path), e);
    }
    return created;
  }