@Override
  public void execute(final ProjectNode node) {
    final MessagesOutput messagesOutput = MessagesOutput.getMessagesOutput();
    messagesOutput.addMessages(MESSAGES.downloadingToPhoneMessage());

    final RpcStatusPopup rpcStatusPopup = Ode.getInstance().getRpcStatusPopup();

    AsyncCallback<Void> callback =
        new AsyncCallback<Void>() {
          @Override
          public void onFailure(Throwable caught) {
            rpcStatusPopup.onFailure(FAKE_RPC_NAME, caught);
            ErrorReporter.reportError(MESSAGES.downloadToPhoneFailedMessage());
            executionFailedOrCanceled();
          }

          @Override
          public void onSuccess(Void result) {
            rpcStatusPopup.onSuccess(FAKE_RPC_NAME, result);
            Window.alert(MESSAGES.downloadToPhoneSucceededMessage());
            executeNextCommand(node);
          }
        };

    String packageName;
    if (node instanceof YoungAndroidProjectNode) {
      YoungAndroidProjectNode yaNode = (YoungAndroidProjectNode) node;
      packageName = yaNode.getPackageNode().getPackageName();
    } else {
      ErrorReporter.reportError(MESSAGES.downloadToPhoneFailedMessage());
      executionFailedOrCanceled();
      return;
    }

    rpcStatusPopup.onStart(FAKE_RPC_NAME);
    String apkFilePath =
        BUILD_FOLDER
            + "/"
            + YoungAndroidProjectNode.YOUNG_ANDROID_TARGET_ANDROID
            + "/"
            + node.getName()
            + ".apk";
    CodeblocksManager.getCodeblocksManager()
        .installApplication(apkFilePath, node.getName(), packageName, callback);
  }
 @Override
 public void execute(ProjectNode node) {
   if (node instanceof YoungAndroidProjectNode) {
     new NewFormDialog((YoungAndroidProjectNode) node).center();
   } else {
     executionFailedOrCanceled();
     throw new IllegalArgumentException("node must be a YoungAndroidProjectNode");
   }
 }
    NewFormDialog(final YoungAndroidProjectNode projectRootNode) {
      super(false, true);

      setStylePrimaryName("ode-DialogBox");
      setText(MESSAGES.newFormTitle());
      VerticalPanel contentPanel = new VerticalPanel();

      final String prefix = "Screen";
      final int prefixLength = prefix.length();
      int highIndex = 0;
      // Collect the existing form names so we can prevent duplicate form names.
      otherFormNames = new HashSet<String>();

      for (ProjectNode source : projectRootNode.getAllSourceNodes()) {
        if (source instanceof YoungAndroidFormNode) {
          String formName = ((YoungAndroidFormNode) source).getFormName();
          otherFormNames.add(formName);

          if (formName.startsWith(prefix)) {
            try {
              highIndex = Math.max(highIndex, Integer.parseInt(formName.substring(prefixLength)));
            } catch (NumberFormatException e) {
              continue;
            }
          }
        }
      }

      String defaultFormName = prefix + (highIndex + 1);

      newNameTextBox = new LabeledTextBox(MESSAGES.formNameLabel());
      newNameTextBox.setText(defaultFormName);
      newNameTextBox
          .getTextBox()
          .addKeyUpHandler(
              new KeyUpHandler() {
                @Override
                public void onKeyUp(KeyUpEvent event) {
                  int keyCode = event.getNativeKeyCode();
                  if (keyCode == KeyCodes.KEY_ENTER) {
                    handleOkClick(projectRootNode);
                  } else if (keyCode == KeyCodes.KEY_ESCAPE) {
                    hide();
                    executionFailedOrCanceled();
                  }
                }
              });
      contentPanel.add(newNameTextBox);

      String cancelText = MESSAGES.cancelButton();
      String okText = MESSAGES.okButton();

      // Keeps track of the total number of screens.
      int formCount = otherFormNames.size() + 1;
      if (formCount > MAX_FORM_COUNT) {
        HorizontalPanel errorPanel = new HorizontalPanel();
        HTML tooManyScreensLabel = new HTML(MESSAGES.formCountErrorLabel());
        errorPanel.add(tooManyScreensLabel);
        errorPanel.setSize("100%", "24px");
        contentPanel.add(errorPanel);

        okText = MESSAGES.addScreenButton();
        cancelText = MESSAGES.cancelScreenButton();

        // okText = "Add";
        // cancelText = "Don't Add";
      }

      Button cancelButton = new Button(cancelText);
      cancelButton.addClickHandler(
          new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
              hide();
              executionFailedOrCanceled();
            }
          });
      Button okButton = new Button(okText);
      okButton.addClickHandler(
          new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
              handleOkClick(projectRootNode);
            }
          });
      HorizontalPanel buttonPanel = new HorizontalPanel();
      buttonPanel.add(cancelButton);
      buttonPanel.add(okButton);
      buttonPanel.setSize("100%", "24px");
      contentPanel.add(buttonPanel);
      contentPanel.setSize("320px", "100%");

      add(contentPanel);
    }
    /**
     * Adds a new form to the project.
     *
     * @param formName the new form name
     */
    protected void addFormAction(
        final YoungAndroidProjectNode projectRootNode, final String formName) {
      final Ode ode = Ode.getInstance();
      final YoungAndroidPackageNode packageNode = projectRootNode.getPackageNode();
      String qualifiedFormName = packageNode.getPackageName() + '.' + formName;
      final String formFileId = YoungAndroidFormNode.getFormFileId(qualifiedFormName);
      final String blocksFileId = YoungAndroidBlocksNode.getBlocklyFileId(qualifiedFormName);

      OdeAsyncCallback<Long> callback =
          new OdeAsyncCallback<Long>(
              // failure message
              MESSAGES.addFormError()) {
            @Override
            public void onSuccess(Long modDate) {
              final Ode ode = Ode.getInstance();
              ode.updateModificationDate(projectRootNode.getProjectId(), modDate);

              // Add the new form and blocks nodes to the project
              final Project project = ode.getProjectManager().getProject(projectRootNode);
              project.addNode(packageNode, new YoungAndroidFormNode(formFileId));
              project.addNode(packageNode, new YoungAndroidBlocksNode(blocksFileId));

              // Add the screen to the DesignToolbar and select the new form editor.
              // We need to do this once the form editor and blocks editor have been
              // added to the project editor (after the files are completely loaded).
              //
              // TODO(sharon): if we create YaProjectEditor.addScreen() and merge
              // that with the current work done in YaProjectEditor.addFormEditor,
              // consider moving this deferred work to the explicit command for
              // after the form file is loaded.
              Scheduler.get()
                  .scheduleDeferred(
                      new Scheduler.ScheduledCommand() {
                        @Override
                        public void execute() {
                          ProjectEditor projectEditor =
                              ode.getEditorManager().getOpenProjectEditor(project.getProjectId());
                          EditorManager.buildHTML();
                          FileEditor formEditor = projectEditor.getFileEditor(formFileId);
                          FileEditor blocksEditor = projectEditor.getFileEditor(blocksFileId);
                          if (formEditor != null && blocksEditor != null && !ode.screensLocked()) {
                            DesignToolbar designToolbar = Ode.getInstance().getDesignToolbar();
                            long projectId = formEditor.getProjectId();
                            designToolbar.addScreen(projectId, formName, formEditor, blocksEditor);
                            designToolbar.switchToScreen(
                                projectId, formName, DesignToolbar.View.FORM);
                            executeNextCommand(projectRootNode);
                          } else {
                            // The form editor and/or blocks editor is still not there. Try again
                            // later.
                            Scheduler.get().scheduleDeferred(this);
                          }
                        }
                      });
            }

            @Override
            public void onFailure(Throwable caught) {
              super.onFailure(caught);
              executionFailedOrCanceled();
            }
          };

      // Create the new form on the backend. The backend will create the form (.scm) and blocks
      // (.blk) files.
      ode.getProjectService().addFile(projectRootNode.getProjectId(), formFileId, callback);
    }