@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);
  }
    /**
     * 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);
    }