public class CustomTypesDialog {  
  private static TextArea optionsTextArea = new TextArea();
  
  /**
   * Creates and shows a dialog window which allows for custom type management.
   *  
   * @param parameterType The listbox of the parameter
   * @param param The parameter node itself
   * @param parentNode The request node of the parameter
   * @param parentTreeItem The tree item of the parameter's request node
   * @param paramCounter The parameter item counter
   * @param paramCounter The parameter item counter
   * @param estimationQualityHtml The type estimation quality string
   */
  public static void show(final ListBox parameterType, final ParamNode param, final GenericNode parentNode, final TreeItem parentTreeItem, final int paramCounter, final HTML estimationQualityHtml) {
    final Button newTypeButton = new Button(GuiFactory.strings.newType());    
    final Button acceptTypeButton = new Button(GuiFactory.strings.acceptType());
    final Button deleteTypeButton = new Button(GuiFactory.strings.deleteType());
    final Button editTypeButton = new Button(GuiFactory.strings.editType());
    final Button closeButton = new Button(GuiFactory.strings.cancel());    
    optionsTextArea.setEnabled(false);
    optionsTextArea.setText("");    
    
    final DialogBox dialog = new DialogBox();
    dialog.setText(GuiFactory.strings.newCustomType());    
    
    final VerticalPanel containerPanel = new VerticalPanel();           
    
    containerPanel.add(new HTML("<br />" + GuiFactory.strings.availableTypes()));
    final ListBox customTypesListBox = new ListBox();
    ParamItem.addCustomTypes(customTypesListBox);
    customTypesListBox.addChangeListener(new ChangeListener() {  
      public void onChange(Widget sender) {
        loadOptions(customTypesListBox.getItemText(customTypesListBox.getSelectedIndex()));
      }      
    });
    String listBoxAndTextBoxWidth = "12em";
    customTypesListBox.setWidth(listBoxAndTextBoxWidth);
    
    containerPanel.add(customTypesListBox);    
    
    // hidden inner panel, pops up and replaces the listbox when a new custom type is entered
    final VerticalPanel innerPanel = new VerticalPanel();
    containerPanel.add(innerPanel);
    innerPanel.setVisible(false);    
    final HorizontalPanel innerContainerPanel = new HorizontalPanel();
    innerPanel.add(innerContainerPanel);
    final TextBox typeTextBox = new TextBox();
    typeTextBox.setText("");
    typeTextBox.setWidth(listBoxAndTextBoxWidth);
    innerContainerPanel.add(typeTextBox);
    final HorizontalPanel innerErrorMessagepanel = new HorizontalPanel();
    innerErrorMessagepanel.setVisible(false);
    innerPanel.add(innerErrorMessagepanel);
    innerErrorMessagepanel.add(new HTML(GuiFactory.strings.fillNamesAndValues()));
    
    //  ok button of the hidden inner panel
    Button okButton = new Button(GuiFactory.strings.ok());    
    okButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if ((typeTextBox.getText().replaceAll("\n", "").length() > 0) && (optionsTextArea.getText().length() > 0)) {
          innerErrorMessagepanel.setVisible(false);
          
          if (!ParamItem.customTypes.contains(typeTextBox.getText())) {
            ParamItem.customTypes.add(typeTextBox.getText());
          }
          Vector options = new Vector();
          String[] optionStrings = optionsTextArea.getText().split("\n");
          for (int i = 0; i < optionStrings.length; i++) {
            if (!options.contains(optionStrings[i])) options.add(optionStrings[i]);
          }
          ParamItem.customTypeOptions.put(typeTextBox.getText(), options);
          ParamItem.addCustomTypesAndClear(customTypesListBox);
          customTypesListBox.setSelectedIndex(getIndexOf(typeTextBox.getText()));
          
          customTypesListBox.setVisible(true);        
          innerPanel.setVisible(false);    
          optionsTextArea.setEnabled(false);
          newTypeButton.setEnabled(true);
          deleteTypeButton.setEnabled(true);
          editTypeButton.setEnabled(true);
          closeButton.setEnabled(true);
          acceptTypeButton.setEnabled(true);
        }
        else {
          innerErrorMessagepanel.setVisible(true);
        }                
      }
    });
    innerContainerPanel.add(okButton);    
    // cancel button of the hidden inner panel
    Button cancelButton = new Button(GuiFactory.strings.cancel());    
    cancelButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {   
        optionsTextArea.setText("");
        typeTextBox.setText("");
        customTypesListBox.setVisible(true);
        innerPanel.setVisible(false);  
        optionsTextArea.setEnabled(false);
        newTypeButton.setEnabled(true);
        deleteTypeButton.setEnabled(true);
        editTypeButton.setEnabled(true);
        closeButton.setEnabled(true);
        acceptTypeButton.setEnabled(true);
      }
    });
    innerContainerPanel.add(cancelButton);
    
    HorizontalPanel newTypePanel = new HorizontalPanel();
    newTypePanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM);
    containerPanel.add(newTypePanel);
    VerticalPanel typesPanel = new VerticalPanel();
    typesPanel.add(new HTML("<br />" + GuiFactory.strings.allowedOptions()));    
    optionsTextArea.setWidth("15em");
    optionsTextArea.setHeight("10em");    
    typesPanel.add(optionsTextArea);
    newTypePanel.add(typesPanel);
    
    VerticalPanel buttonPanel = new VerticalPanel();
    
    // new type button
    String buttonWidth = "10em";
    newTypeButton.setWidth(buttonWidth);
    newTypeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {             
        customTypesListBox.setVisible(false);        
        innerPanel.setVisible(true);
        typeTextBox.setText("");
        typeTextBox.setFocus(true);
        optionsTextArea.setText("");
        optionsTextArea.setEnabled(true);
        newTypeButton.setEnabled(false);
        editTypeButton.setEnabled(false);
        deleteTypeButton.setEnabled(false);
        closeButton.setEnabled(false);
        acceptTypeButton.setEnabled(false);
      }
    });
    buttonPanel.add(newTypeButton);   
    
    // edit type button
    editTypeButton.setWidth(buttonWidth);
    buttonPanel.add(editTypeButton);        
    editTypeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (customTypesListBox.getItemCount() > 0) {
          customTypesListBox.setVisible(false);    
          newTypeButton.setEnabled(false);
          editTypeButton.setEnabled(false);
          deleteTypeButton.setEnabled(false);
          closeButton.setEnabled(false);
          acceptTypeButton.setEnabled(false);
          String oldName = customTypesListBox.getItemText(customTypesListBox.getSelectedIndex());
          typeTextBox.setText(oldName);         
          optionsTextArea.setEnabled(true);
          innerPanel.setVisible(true);          
        }
      }
    });
    
    // delete type button
    deleteTypeButton.setWidth(buttonWidth);
    buttonPanel.add(deleteTypeButton);        
    newTypePanel.add(buttonPanel);
    deleteTypeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (customTypesListBox.getItemCount() > 0) {             
          String selectedCustomType = customTypesListBox.getItemText(customTypesListBox.getSelectedIndex());
          ParamItem.customTypes.remove(selectedCustomType);
          ParamItem.customTypeOptions.remove(selectedCustomType);          
          customTypesListBox.removeItem(customTypesListBox.getSelectedIndex());
          optionsTextArea.setText("");
          if (param.getType().equals(selectedCustomType)) {
            param.setOptions(new Vector());            
          }
          if (customTypesListBox.getItemCount() > 0) {
            loadOptions(customTypesListBox.getItemText(customTypesListBox.getSelectedIndex()));
          }
        }
      }
    });
   
    // accept type button
    acceptTypeButton.addClickListener(new ClickListener() {    
      public void onClick(Widget sender) {
        GuiFactory.blockScreen(false);
        if (customTypesListBox.getItemCount() > 0) {
          ParamItem.addTypes(parameterType);        
          String selectedCustomType = customTypesListBox.getItemText(customTypesListBox.getSelectedIndex());
          parameterType.setSelectedIndex(ParamItem.indexOfValue(selectedCustomType));          
        
          param.updateType(param.getType(), selectedCustomType);
          param.setEstimateQuality(TypeEstimator.manual);
          param.setOptions((Vector) ParamItem.customTypeOptions.get(selectedCustomType));                    
        }
        ParamItem.listParams(
            parentNode,
            parentTreeItem, 
            parentNode.getApplication().getAnalyzer().getRequestString());       
        parentTreeItem.getChild(paramCounter).setSelected(true);
        parentTreeItem.getTree().ensureSelectedItemVisible();

        dialog.hide();        
      }
    });
    acceptTypeButton.setWidth(buttonWidth);
    
    // close button
    closeButton.setWidth(buttonWidth);
    closeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        ParamItem.listParams(
            parentNode,
            parentTreeItem,
            parentNode.getApplication().getAnalyzer().getRequestString());       
        parentTreeItem.getChild(paramCounter).setSelected(true);
        parentTreeItem.getTree().ensureSelectedItemVisible();
        GuiFactory.blockScreen(false);
        dialog.hide();
      }
    });
    
    containerPanel.add(new HTML("<br />&nbsp;"));
    HorizontalPanel okClosePanel = new HorizontalPanel();
    okClosePanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    okClosePanel.setWidth("100%");    
    okClosePanel.add(acceptTypeButton);
    okClosePanel.add(closeButton);
    containerPanel.add(okClosePanel);
  
    if (ParamItem.customTypes.size() > 0) {
      loadOptions(customTypesListBox.getItemText(customTypesListBox.getSelectedIndex()));
    }
    
    dialog.setWidget(containerPanel);
    dialog.setPopupPosition((int) Math.floor(Window.getClientWidth() * 0.4), (int) Math.floor(Window.getClientHeight() * 0.2));
    GuiFactory.blockScreen(true);
    dialog.show();    
  }

  /**
   * Returns the index of a listbox item string
   * @param text The listbox item string
   * @return The item's index
   */
  private static int getIndexOf(String text) {    
    for (int i = 0; i < ParamItem.customTypes.size(); i++) {
      if (((String) ParamItem.customTypes.elementAt(i)).equals(text)) return i;
    }
    return -1;    
  }
  
  /**
   * Loads the valid type options for a given custom type
   * @param selected The custom type name
   */
  private static void loadOptions(String selected) {    
    Vector options = (Vector) ParamItem.customTypeOptions.get(selected);
    Iterator optionsIterator = options.iterator();
    optionsTextArea.setText("");
    while(optionsIterator.hasNext()) {
      optionsTextArea.setText(optionsTextArea.getText() + (String) optionsIterator.next() + "\n"); 
    }
  }
} public class GuiFactory implements WindowResizeListener {
  private static DockPanel blockScreen;
  public static Strings strings;
  public static Notifications notifications;  
  private DockPanel dockPanel;
  public static final String restCompile = "restCompile";
  public static final String restDescribe = "restDescribe";
  
	/**
	 * Creates the GUI consisting of various panels
	 */
	public GuiFactory() {
    // I18N strings
    strings = (Strings) GWT.create(Strings.class);
    notifications = (Notifications) GWT.create(Notifications.class);
   
    // disallow scrolling
    Window.enableScrolling(false);
    // resize the panels on main window resize
    Window.addWindowResizeListener(this);        
    
    // main application
    dockPanel = new DockPanel();    
    dockPanel.setStyleName("restDescribe-mainApplicationPanel");
    dockPanel.setWidth("99.7%");
    dockPanel.setHeight("99.7%");    
    dockPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);    
    dockPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);    

    // main menu
    MainMenuPanel mainMenuPanel = new MainMenuPanel();    
    dockPanel.add(mainMenuPanel, DockPanel.NORTH);
    dockPanel.setCellHeight(mainMenuPanel, "10%");

    // rest compile panel
    RestCompilePanel restCompilePanel = new RestCompilePanel();    
    dockPanel.add(restCompilePanel, DockPanel.NORTH);
    
    // request sample panel    
    RequestUriPanel requestUriPanel = new RequestUriPanel();
    dockPanel.add(requestUriPanel, DockPanel.NORTH);
    dockPanel.setCellHeight(requestUriPanel, "10%");    
    
    // navigation panel
    ParameterPanel parameterPanel = new ParameterPanel();    
    dockPanel.add(parameterPanel, DockPanel.WEST);
    dockPanel.setCellHeight(parameterPanel, "80%");
    dockPanel.setCellWidth(parameterPanel, "45%");
    dockPanel.setCellVerticalAlignment(parameterPanel, HasVerticalAlignment.ALIGN_TOP);
    
    // wadl panel
    WadlPanel wadlPanel = new WadlPanel();
    dockPanel.add(wadlPanel, DockPanel.EAST);    
    dockPanel.setCellHeight(wadlPanel, "80%");
    dockPanel.setCellWidth(wadlPanel, "55%");
    dockPanel.setCellVerticalAlignment(wadlPanel, HasVerticalAlignment.ALIGN_TOP);
    
    toggleMode(restDescribe);
    
		RootPanel.get().add(dockPanel);
    
    // semi-transparent screen blocker for dialogs
    blockScreen = new DockPanel();        
    HTML semiTransparentDiv = getBlockedScreenDiv(Window.getClientWidth(), Window.getClientHeight());
    blockScreen.add(semiTransparentDiv, DockPanel.SOUTH);
    blockScreen.setVisible(false);    
    RootPanel.get().add(blockScreen);

    onWindowResized(Window.getClientWidth(), Window.getClientHeight());
    
    // reset the application
    GuiFactory.resetApplication(GuiFactory.strings.newRequestUri());
	}
  
  /* (non-Javadoc)
   * @see com.google.gwt.user.client.WindowResizeListener#onWindowResized(int, int)
   */
  public void onWindowResized(int width, int height) {    
    RequestUriPanel.requestSampleArea.setHeight(Math.floor(0.1 * height) + "px");    
    RequestUriPanel.containerPanel.setWidth(Math.floor(0.97 * width) + "px");
    
    int panelHeight = height - RequestUriPanel.requestSamplePanel.getOffsetHeight() - MainMenuPanel.menuPanel.getOffsetHeight() - WadlPanel.wadlHeader.getOffsetHeight() - 80;    
    ParameterPanel.parameterPanel.setHeight("100%");
    ParameterPanel.parameterPanel.setWidth("100%");
    ParameterPanel.requestArea.setHeight(panelHeight + "px");
    ParameterPanel.requestArea.setWidth(Math.floor(0.28 * width) + "px");
                
    WadlPanel.wadlPanel.setHeight("100%");
    WadlPanel.wadlPanel.setWidth("95%");    
    
    WadlPanel.wadlArea.setHeight(panelHeight + "px");
    WadlPanel.wadlArea.setWidth(Math.floor(0.58 * width) + "px");    
    
    GuiFactory.blockScreen.clear();
    GuiFactory.blockScreen.add(getBlockedScreenDiv(width, height), DockPanel.NORTH);    
  }
  
  /**
   * Blocks the screen by means of a semi transparent blocking layer when dialogs are shown 
   * @param isVisible Determines whether or not to display the blocking layer
   */
  public static void blockScreen(boolean isVisible) {
    blockScreen.setVisible(isVisible);
  }
  
  /**
   * Dynamically creates the semi transparent blocking layer html
   * @param width Current screen width
   * @param height Current screen height
   * @return The blocking layer html
   */
  private static HTML getBlockedScreenDiv(int width, int height) {
    return new HTML("<div style='z-index:0; width:" + width + "px; height:" + height + "px; position:absolute; left:0px; top:0px; background-color:black; opacity:.40; filter: alpha(opacity=40);'>&nbsp;</div>");
  }
  
  /**
   * Resets the application and loads an initial request string
   * @param initialRequestString The initial request string
   */
  public static void resetApplication(String initialRequestString) {
    resetApplication();
    ReferenceManager.allRequestStrings.add(initialRequestString);      
    RequestUriTree.listRequestSamples(ReferenceManager.allRequestStrings);    
  }
  
  public static void toggleButtonsEnabled(boolean isEnabled) {
    WadlPanel.wadlSaveButton.setEnabled(isEnabled);
    WadlPanel.wadlPreviewButton.setEnabled(isEnabled);
    WadlPanel.resetButton.setEnabled(isEnabled);
    WadlPanel.fullscreenButton.setEnabled(isEnabled);
    WadlPanel.generateCodeButton.setEnabled(isEnabled);
  }
  
  public static void toggleMode(String mode) {
    boolean toggleBit = false;
    if (mode.equals(restCompile)) {
      toggleBit = true;
      if (FullscreenDialog.leaveFullscreenButton != null) {
        FullscreenDialog.leaveFullscreenButton.click();
      }
      RestCompilePanel.codeTextArea.setText("");
      RestCompilePanel.buttonPanel.setVisible(false);
      RestCompilePanel.compilePanel.setVisible(false);      
      MainMenuPanel.logo.setHTML(MainMenuPanel.restCompileLogo);
    }
    else if (mode.equals(restDescribe)) {
      toggleBit = false;
      MainMenuPanel.logo.setHTML(MainMenuPanel.restDescribeLogo);
    }    
    
    WadlPanel.wadlPanel.setVisible(!toggleBit);
    RequestUriPanel.requestSamplePanel.setVisible(!toggleBit);
    ParameterPanel.parameterPanel.setVisible(!toggleBit);
    RestCompilePanel.restCompilePanel.setVisible(toggleBit);
    
    int width = Window.getClientWidth();
    int height = Window.getClientHeight();
    RequestUriPanel.requestSampleArea.setHeight(Math.floor(0.1 * height) + "px");    
    RequestUriPanel.containerPanel.setWidth(Math.floor(0.97 * width) + "px");
    
    int panelHeight = height - RequestUriPanel.requestSamplePanel.getOffsetHeight() - MainMenuPanel.menuPanel.getOffsetHeight() - WadlPanel.wadlHeader.getOffsetHeight() - 80;    
    ParameterPanel.parameterPanel.setHeight("100%");
    ParameterPanel.parameterPanel.setWidth("100%");
    ParameterPanel.requestArea.setHeight(panelHeight + "px");
    ParameterPanel.requestArea.setWidth(Math.floor(0.28 * width) + "px");
                
    WadlPanel.wadlPanel.setHeight("100%");
    WadlPanel.wadlPanel.setWidth("95%");    
    
    WadlPanel.wadlArea.setHeight(panelHeight + "px");
    WadlPanel.wadlArea.setWidth(Math.floor(0.58 * width) + "px");  
  }

  /**
   * Resets the application without loading an inital uri
   */
  public static void resetApplication() {
    RestCompilePanel.paramToUseForName = "";    
    RequestUriPanel.uriTree.removeItems();    
    ParameterPanel.requestContainer.clear();
    WadlPanel.wadlArea.clear();
    if (Analyzer.application != null) {      
      Analyzer.application.reset();      
    }
    ReferenceManager.clearReferences();
    toggleButtonsEnabled(false);    
  }
}
 public class ParameterTree {  
  public Button addParamButton;  
  private Button reAnalyzeButton;    
  public TreeItem requestItem;
  public Tree requestTree = new Tree();
  public String requestString;
     
  /**
   * Initializes the request parameter tree
   * @param requestString 
   * @param requestSampleTextBox The current request uri textbox
   * @param analyzeButton The current start analyze button
   */
  public ParameterTree(String request) {
    this.requestString = request;    
  }
  
  /**
   * Creates the request parameter tree
   * @return The request parameter tree
   */
  public void buildTree() {        
    requestItem = new TreeItem();    
    requestTree.addItem(requestItem);
    
    updateTree();
    
    // reanalyze button
    HorizontalPanel buttonPanel = new HorizontalPanel();
    reAnalyzeButton = new Button(GuiFactory.strings.reAnalyzeRequest());
    reAnalyzeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {       
        Button startAnalyzeButton = ReferenceManager.getStartAnalyzeButton(requestString);
        startAnalyzeButton.click();
      }      
    });
    buttonPanel.add(reAnalyzeButton);    
    buttonPanel.add(new HTML("&nbsp;"));
    
    // add param button
    addParamButton = new Button(GuiFactory.strings.addParameter());
    addParamButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {       
        addParam();        
      }      
    });    
    buttonPanel.add(addParamButton);
    requestTree.addItem(buttonPanel);
        
    ParameterPanel.requestContainer.add(requestTree);
  }

  private void updateRequestName(Uri uri) { 
    String[] parameters = uri.getQueryParameters();
    String requestName = null;
    paramSearch:
      for (int i = 0; i < parameters.length; i++) {
        for (int j = 0; j < RestCompilePanel.commonOpParamNames.length; j++) {
          if (parameters[i].equalsIgnoreCase(RestCompilePanel.commonOpParamNames[j])) {
            requestName = uri.getQueryValues()[i];
            SettingsDialog.useEndpointAsName = false;
            break paramSearch;
          }
        }
      }
    if (requestName == null) {
      requestName = uri.getRequest();
      SettingsDialog.useEndpointAsName = true;
    }
    requestName = CodeGenerator.cleanName(requestName, false);
    requestItem.setHTML("<b>" + requestName + "</b> " + GuiFactory.strings.listOfParams());
  }
      
  /**
   * Updates the current references of the class in case where the request uri tree has been rebuild 
   * @param newUri 
   * @param requestUriTextBox
   */
  public void updateReferences(TextBox requestUriTextBox, String newUri) {
    requestUriTextBox.setText(newUri);    
    ListBox httpMethod = ReferenceManager.getHttpMethodListBox(requestString);
    String newRequestString =
        httpMethod.getItemText(httpMethod.getSelectedIndex()) + " " + newUri;
    if (!requestString.equals(newRequestString)) {
      ReferenceManager.updateAllReferences(requestString, newRequestString);
    }
    requestString = newRequestString;
    
  }

  /**
   * Updates the request parameter tree in case of where the request uri got changed
   * @param uri The new request uri
   */
  public void updateTree() {
    Uri uri = new Uri(requestString.substring(requestString.indexOf(" ") + 1));   
    updateRequestName(uri);
    requestItem.removeItems();    
        
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();     
    for (int i = 0; i < queryParameters.length; i++) {
      final HorizontalPanel containerPanel = new HorizontalPanel(); 
      final TreeItem parameterItem = new TreeItem(containerPanel);
      // parameter name label
      HTML parameterName = new HTML("<nobr/>" + queryParameters[i] + " =&nbsp;</nobr>");            
      containerPanel.add(parameterName);
      // parameter value textbox
      final TextBox queryValueTextBox = new TextBox(); 
      queryValueTextBox.setWidth("10em");
      queryValueTextBox.setText(queryValues[i]);
      // track parameter value changes
      final String currentParameter = queryParameters[i];      
      queryValueTextBox.addKeyboardListener(new KeyboardListener() {
        public void onKeyDown(Widget sender, char keyCode, int modifiers) {
          // empty
        }

        public void onKeyPress(Widget sender, char keyCode, int modifiers) {
          // empty
        }

        public void onKeyUp(Widget sender, char keyCode, int modifiers) {
          updateParameterValue(currentParameter, queryValueTextBox.getText());
        }        
      });
      queryValueTextBox.addChangeListener(new ChangeListener() {
        public void onChange(Widget sender) {
          updateParameterValue(currentParameter, queryValueTextBox.getText());
        }
      });
      containerPanel.add(queryValueTextBox);
      
      // remove parameter link
      Hyperlink removeParameterLink = new Hyperlink(GuiFactory.strings.remove(), true, "");
      removeParameterLink.addClickListener(new ClickListener() {
        public void onClick(Widget sender) {
          removeHyperlink(parameterItem, queryValueTextBox.getText());
        }
      });
      containerPanel.add(removeParameterLink);      
      requestItem.addItem(parameterItem);
      parameterItem.setState(true);
    }    
    requestItem.setState(true);    
  }

  /**
   * 
   */
  private void removeHyperlink(TreeItem parameterItem, String queryValue) {
    parameterItem.remove();
    TextBox requestUriTextBox = ReferenceManager.getRequestUriTextBox(requestString);
    Uri uri = new Uri(requestUriTextBox.getText());
    String newUri = uri.getScheme() + "://" + uri.getAuthority() + uri.getPath() + "?";
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();
    for (int i = 0; i < queryParameters.length; i++) {
      if (!queryValues[i].equals(queryValue)) {
        if (i > 0) newUri += "&";       
        newUri += queryParameters[i] + "=" + queryValues[i];
      }
    }
    newUri += uri.getFragment();
    updateReferences(requestUriTextBox, newUri);    
  }

  private void updateParameterName(String queryParameter, String queryValue) {
    TextBox requestUriTextBox = ReferenceManager.getRequestUriTextBox(requestString);
    Uri uri = new Uri(requestUriTextBox.getText());
    String newUri = uri.getScheme() + "://" + uri.getAuthority() + uri.getPath() + "?";
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();
    for (int i = 0; i < queryParameters.length; i++) {
      if (i > 0) newUri += "&";            
      if (queryValues[i].equals(queryValue)) {              
        newUri += queryParameter + "=" + queryValues[i];
      }
      else {
        newUri += queryParameters[i] + "=" + queryValues[i];
      }          
    }  
    newUri += uri.getFragment();
    updateReferences(requestUriTextBox, newUri);
  }  
  
  /**
   * @param queryParameter 
   * @param queryValueTextBox 
   * 
   */
  private void updateParameterValue(String queryParameter, String queryValue) {
    TextBox requestUriTextBox = ReferenceManager.getRequestUriTextBox(requestString);
    String newRequestUriString = requestUriTextBox.getText();
    Uri uri = new Uri(newRequestUriString);
    String newUri = uri.getScheme() + "://" + uri.getAuthority() + uri.getPath() + "?";
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();
    for (int i = 0; i < queryParameters.length; i++) {
      if (i > 0) newUri += "&";            
      if (queryParameters[i].equals(queryParameter)) {              
        newUri += queryParameters[i] + "=" + queryValue;
      }
      else {
        newUri += queryParameters[i] + "=" + queryValues[i];
      }            
    }  
    newUri += uri.getFragment();
    updateReferences(requestUriTextBox, newUri);    
  }

  /**
   * Adds a parameter to the current request uri tree and in consequence to the request parameter tree.
   */
  public void addParam() { 
    TextBox requestUriTextBox = ReferenceManager.getRequestUriTextBox(requestString);
    Uri uri = new Uri(requestUriTextBox.getText());    
    final HorizontalPanel containerPanel = new HorizontalPanel();
    final TreeItem parameterItem = new TreeItem(containerPanel);
    // parameter name textbox
    final TextBox queryParamNameTextBox = new TextBox();
    queryParamNameTextBox.setWidth("10em");
    // parameter value textbox
    final TextBox queryValueTextBox = new TextBox(); 
    queryValueTextBox.setWidth("10em");
    final String currentParameter = GuiFactory.strings.paramName();
    final String currentValue = GuiFactory.strings.paramValue();    
    String newUri = uri.getScheme() + "://" + uri.getAuthority() + uri.getPath() + "?";
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();
    for (int i = 0; i < queryParameters.length; i++) {
      if (i > 0) {
        newUri += "&";        
      }
      newUri += queryParameters[i] + "=" + queryValues[i];       
    }
    newUri += "&" + currentParameter + "=" + currentValue + uri.getFragment();
    updateReferences(requestUriTextBox, newUri);    
    queryParamNameTextBox.addKeyboardListener(new KeyboardListener() {
      public void onKeyDown(Widget sender, char keyCode, int modifiers) {
        // empty
      }

      public void onKeyPress(Widget sender, char keyCode, int modifiers) {
        // empty
      }

      public void onKeyUp(Widget sender, char keyCode, int modifiers) {
        updateParameterName(queryParamNameTextBox.getText(), queryValueTextBox.getText());
      }
    });
    queryParamNameTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        updateParameterName(queryParamNameTextBox.getText(), queryValueTextBox.getText());
      }
    });
    queryParamNameTextBox.setText(GuiFactory.strings.paramName());
    containerPanel.add(queryParamNameTextBox);
    queryParamNameTextBox.setSelectionRange(0, queryParamNameTextBox.getText().length());      
    HTML parameterName = new HTML("<nobr/> =&nbsp;</nobr>");
    containerPanel.add(parameterName);     
    queryValueTextBox.addKeyboardListener(new KeyboardListener() {
      public void onKeyDown(Widget sender, char keyCode, int modifiers) {
        // empty
      }

      public void onKeyPress(Widget sender, char keyCode, int modifiers) {
        // empty
      }

      public void onKeyUp(Widget sender, char keyCode, int modifiers) {
        updateParameterValue(queryParamNameTextBox.getText(), queryValueTextBox.getText());        
      }
      
    });
    queryValueTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {      
        updateParameterValue(queryParamNameTextBox.getText(), queryValueTextBox.getText());        
      }
    });
    queryValueTextBox.setText(GuiFactory.strings.paramValue());
    containerPanel.add(queryValueTextBox);    
    
    Hyperlink removeParameterLink = new Hyperlink(GuiFactory.strings.remove(), true, "");
    removeParameterLink.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        removeHyperlink(parameterItem, queryValueTextBox.getText());
      }
    });      
    containerPanel.add(removeParameterLink);
    requestItem.addItem(parameterItem);    
    parameterItem.setState(true);    
  }  
} public class SettingsDialog {
  public static boolean alwaysShowDetails = false;
  public static boolean alwaysShowDetailsTemp = alwaysShowDetails;
  public static boolean treeItemsAlwaysOpen = true;
  public static boolean treeItemsAlwaysOpenTemp = treeItemsAlwaysOpen;
  public static int requestTimeoutSeconds = 180;
  public static int namingDepthLevel = 1;
  public static String pathToDiscoverer = "./resources/Discoverer.php5";
  public static String pathToJsonConverter = "./resources/XML2JSON.php5";
  public static boolean useEndpointAsName = true;
  public static String separationCharacter = "_";
  public static boolean useSeparationCharacter = false;
  public static boolean useSeparationCharacterTemp = useSeparationCharacter;
  public static String classDefaultSuffix = "";
  public static int indentWidth = 2;
  public static boolean indentWithSpaces = true; 
  public static String templateSuffix = ""; //"_TEMPLATE";  
  private static final String confirm_de = "<a href=\"RestDescribe.html?locale=de\">" + GuiFactory.strings.confirmAndRestart() + "</a>";   
  private static final String confirm_enUS = "<a href=\"RestDescribe.html?locale=en\">" + GuiFactory.strings.confirmAndRestart() + "</a>";
  private static final String confirm_ca = "<a href=\"RestDescribe.html?locale=ca\">" + GuiFactory.strings.confirmAndRestart() + "</a>";

  /**
   * Creates the settings dialog
   */
  public static void show() {
    String panelHeight = "3em";
    String panelWidthLeft = "15em";
    String panelWidthRight = "20em";
    String textBoxWidth = "8em";
    final DialogBox dialogBox = new DialogBox();    
    dialogBox.setText(GuiFactory.strings.settingsLink());    
       
    VerticalPanel settingsPanel = new VerticalPanel();   
    TabPanel tabPanel = new TabPanel();   
        
    final ListBox languageListBox = new ListBox();   
    languageListBox.addItem(GuiFactory.strings.english_US());
    languageListBox.addItem(GuiFactory.strings.german());
    languageListBox.addItem(GuiFactory.strings.catalan());
        
    VerticalPanel generalPanel = new VerticalPanel(); 
     
    HorizontalPanel languagePanel = new HorizontalPanel();   
    languagePanel.setHeight(panelHeight);
    HorizontalPanel languagePanelLeft = new HorizontalPanel();
    HorizontalPanel languagePanelRight = new HorizontalPanel();
     
    languagePanelLeft.setWidth(panelWidthLeft);
    languagePanelLeft.add(new HTML("<b>" + GuiFactory.strings.language() + "</b>"));   
    languagePanelRight.setWidth(panelWidthRight);
    languagePanelRight.add(new HTML(GuiFactory.strings.displayRestDescribe() + ":&nbsp;"));
    languagePanelRight.add(languageListBox);   
        
    languagePanel.add(languagePanelLeft);
    languagePanel.add(languagePanelRight);   
    generalPanel.add(languagePanel);
     
    final HorizontalPanel confirmLangChange =  new HorizontalPanel();
    confirmLangChange.setVisible(false);
    confirmLangChange.add(new HTML(GuiFactory.strings.cautionChangesGetLost() + "&nbsp;"));
       
    final HTML confirmLink = new HTML("");
    confirmLangChange.add(confirmLink);
    confirmLangChange.add(new HTML("."));   
    generalPanel.add(confirmLangChange);   
    languageListBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {       
        updateAndDisplayConfirmLink(languageListBox.getItemText(languageListBox.getSelectedIndex()), confirmLink, confirmLangChange);
      }
    });
    languageListBox.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        updateAndDisplayConfirmLink(languageListBox.getItemText(languageListBox.getSelectedIndex()), confirmLink, confirmLangChange);
      }     
    });
     
    final CheckBox detailsCheckBox = new CheckBox();
    detailsCheckBox.setChecked(alwaysShowDetails);
    detailsCheckBox.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (detailsCheckBox.isChecked()) {
          alwaysShowDetailsTemp = true;        
        }
        else {
          alwaysShowDetailsTemp = false;
        }
      }
    });
       
    final CheckBox treesCheckBox = new CheckBox();
    treesCheckBox.setChecked(treeItemsAlwaysOpen);
    treesCheckBox.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (treesCheckBox.isChecked()) {
          treeItemsAlwaysOpenTemp = true;        
        }
        else {
          treeItemsAlwaysOpenTemp = false;
        }
      }
    });
    
    final HorizontalPanel miniSepTextPanel = new HorizontalPanel();
    final CheckBox useSeparationCharacterCheckBox = new CheckBox();
    useSeparationCharacterCheckBox.setChecked(useSeparationCharacter);
    useSeparationCharacterCheckBox.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        if (useSeparationCharacterCheckBox.isChecked()) {
          useSeparationCharacterTemp = true;        
        }
        else {
          useSeparationCharacterTemp = false;
        }
        miniSepTextPanel.setVisible(useSeparationCharacterTemp);
      }
    });
     
    final TextBox timeoutSecondsTextBox = new TextBox();
    timeoutSecondsTextBox.setText(Integer.toString(requestTimeoutSeconds));
    timeoutSecondsTextBox.setWidth(panelHeight);
    timeoutSecondsTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        try {
          requestTimeoutSeconds = Integer.parseInt(timeoutSecondsTextBox.getText());
          timeoutSecondsTextBox.removeStyleName("restDescribe-error");
        } catch (NumberFormatException e) {    
          timeoutSecondsTextBox.setStyleName("restDescribe-error");
        }
      }     
    });   
    
    miniSepTextPanel.setVisible(useSeparationCharacter);
    final TextBox separationCharacterTextBox = new TextBox();    
    separationCharacterTextBox.setText(separationCharacter);
    separationCharacterTextBox.setWidth(panelHeight);
    separationCharacterTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        separationCharacter = separationCharacterTextBox.getText();
      }     
    });
     
    final TextBox namingDepthTextBox = new TextBox();
    namingDepthTextBox.setText(Integer.toString(namingDepthLevel));
    namingDepthTextBox.setWidth(panelHeight);
    namingDepthTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        try {
          namingDepthLevel = Integer.parseInt(namingDepthTextBox.getText());
          namingDepthTextBox.removeStyleName("restDescribe-error");
          if (SettingsDialog.namingDepthLevel == 0) {
            namingDepthTextBox.setStyleName("restDescribe-error");
          }
        } catch (NumberFormatException e) {    
          namingDepthTextBox.setStyleName("restDescribe-error");
        }
      }     
    });
    
    final RadioButton useParameterAsNameRadio = new RadioButton("paramOrEndpoint", GuiFactory.strings.useParam());
    useParameterAsNameRadio.setChecked(!useEndpointAsName);
    useParameterAsNameRadio.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        useEndpointAsName = !useParameterAsNameRadio.isChecked();        
      }      
    });
    
    final RadioButton useEndpointAsNameRadio = new RadioButton("paramOrEndpoint", GuiFactory.strings.useEndpoint());
    useEndpointAsNameRadio.setChecked(useEndpointAsName);
    useEndpointAsNameRadio.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        useEndpointAsName = useEndpointAsNameRadio.isChecked();
      }      
    });
    
    final TextBox indentWidthTextBox = new TextBox();
    indentWidthTextBox.setWidth(panelHeight);
    indentWidthTextBox.setText(indentWidth + "");
    indentWidthTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        try {
          indentWidth = Integer.parseInt(indentWidthTextBox.getText());
          indentWidthTextBox.removeStyleName("restDescribe-error");
          if (SettingsDialog.indentWidth == 0) {
            indentWidthTextBox.setStyleName("restDescribe-error");
          }
        } catch (NumberFormatException e) {    
          indentWidthTextBox.setStyleName("restDescribe-error");
        }        
      }      
    });
    
    final HorizontalPanel indentMiniPanel = new HorizontalPanel();
    final RadioButton indentWithSpacesRadio = new RadioButton("indent", GuiFactory.strings.indentSpaces());
    indentWithSpacesRadio.setChecked(indentWithSpaces);
    indentWithSpacesRadio.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        indentWithSpaces = indentWithSpacesRadio.isChecked();
        indentMiniPanel.setVisible(true);
      }      
    });
    
    final RadioButton indentWithTabsRadio = new RadioButton("indent", GuiFactory.strings.indentTabs());
    indentWithTabsRadio.setChecked(!indentWithSpaces);
    indentWithTabsRadio.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {        
        indentWithSpaces = !indentWithTabsRadio.isChecked();
        indentMiniPanel.setVisible(false);
      }      
    });
    
    final TextBox classSuffixTextBox = new TextBox();
    classSuffixTextBox.setText(classDefaultSuffix);
    classSuffixTextBox.setWidth(textBoxWidth);
    classSuffixTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {
        classDefaultSuffix = classSuffixTextBox.getText();        
      }
    });
     
    final TextBox pathToDiscovererTextBox = new TextBox();
    pathToDiscovererTextBox.setText(pathToDiscoverer);
    pathToDiscovererTextBox.setWidth(textBoxWidth);
    pathToDiscovererTextBox.addChangeListener(new ChangeListener() {
      public void onChange(Widget sender) {        
        pathToDiscoverer = pathToDiscovererTextBox.getText();        
      }     
    });
    
    // preferences
    VerticalPanel preferencesPanel = new VerticalPanel(); 
    preferencesPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
     
    // details
    HorizontalPanel detailsPanel = new HorizontalPanel(); 
    detailsPanel.setHeight(panelHeight);
    HorizontalPanel detailsPanelLeft = new HorizontalPanel();
    HorizontalPanel detailsPanelRight = new HorizontalPanel();   
    detailsPanelLeft.setWidth(panelWidthLeft);
    detailsPanelLeft.add(new HTML("<b>" + GuiFactory.strings.details() + "</b>"));
    detailsPanelRight.setWidth(panelWidthRight);
    detailsPanelRight.add(detailsCheckBox);
    detailsPanelRight.add(new HTML(GuiFactory.strings.displayDetails()));
    detailsPanel.add(detailsPanelLeft);
    detailsPanel.add(detailsPanelRight);   
    preferencesPanel.add(detailsPanel);
     
    // tree items open
    HorizontalPanel treesPanel = new HorizontalPanel(); 
    treesPanel.setHeight(panelHeight);
    HorizontalPanel treesPanelLeft = new HorizontalPanel();
    HorizontalPanel treesPanelRight = new HorizontalPanel();   
    treesPanelLeft.setWidth(panelWidthLeft);
    treesPanelLeft.add(new HTML("<b>" + GuiFactory.strings.treesOpen() + "</b>"));
    treesPanelRight.setWidth(panelWidthRight);
    treesPanelRight.add(treesCheckBox);
    treesPanelRight.add(new HTML(GuiFactory.strings.treesAlwaysOpen()));
    treesPanel.add(treesPanelLeft);
    treesPanel.add(treesPanelRight);   
    preferencesPanel.add(treesPanel);
         
    // request tab
    VerticalPanel requestPanel = new VerticalPanel(); 
    requestPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);

    // path to discoverer
    HorizontalPanel pathPanel = new HorizontalPanel();
    pathPanel.setHeight(panelHeight);
    HorizontalPanel pathPanelLeft = new HorizontalPanel();
    HorizontalPanel pathPanelRight = new HorizontalPanel();
    pathPanelLeft.setWidth(panelWidthLeft);
    pathPanelLeft.add(new HTML("<b>" + GuiFactory.strings.pathDiscover() + "</b>"));
    pathPanelRight.setWidth(panelWidthRight);
    pathPanelRight.add(pathToDiscovererTextBox);
    pathPanelRight.add(new HTML(GuiFactory.strings.pathToDiscoverer()));   
    pathPanel.add(pathPanelLeft);
    pathPanel.add(pathPanelRight);   
    requestPanel.add(pathPanel);
    
    // timeout
    HorizontalPanel timeoutPanel = new HorizontalPanel();
    timeoutPanel.setHeight(panelHeight);
    HorizontalPanel timeoutPanelLeft = new HorizontalPanel();
    HorizontalPanel timeoutPanelRight = new HorizontalPanel();
    timeoutPanelLeft.setWidth(panelWidthLeft);
    timeoutPanelLeft.add(new HTML("<b>" + GuiFactory.strings.timeout() + "</b>"));
    timeoutPanelRight.setWidth(panelWidthRight);
    timeoutPanelRight.add(timeoutSecondsTextBox);
    timeoutPanelRight.add(new HTML(GuiFactory.strings.timeoutSeconds()));   
    timeoutPanel.add(timeoutPanelLeft);
    timeoutPanel.add(timeoutPanelRight);   
    requestPanel.add(timeoutPanel);
    
    // code generation tab
    VerticalPanel codeGenerationPanel = new VerticalPanel(); 
    codeGenerationPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
    
    // naming depth
    HorizontalPanel namingDepthPanel = new HorizontalPanel();
    namingDepthPanel.setHeight(panelHeight);
    HorizontalPanel namingDepthPanelLeft = new HorizontalPanel();
    HorizontalPanel namingDepthPanelRight = new HorizontalPanel();
    namingDepthPanelLeft.setWidth(panelWidthLeft);
    namingDepthPanelLeft.add(new HTML("<b>" + GuiFactory.strings.namingDepth() + "</b>"));
    namingDepthPanelRight.setWidth(panelWidthRight);
    namingDepthPanelRight.add(namingDepthTextBox);
    namingDepthPanelRight.add(new HTML(GuiFactory.strings.namingDepthLevel()));   
    namingDepthPanel.add(namingDepthPanelLeft);
    namingDepthPanel.add(namingDepthPanelRight);   
    codeGenerationPanel.add(namingDepthPanel);
    
    // class default suffix
    HorizontalPanel classSuffixPanel = new HorizontalPanel();
    classSuffixPanel.setHeight(panelHeight);
    HorizontalPanel classSuffixPanelLeft = new HorizontalPanel();
    HorizontalPanel classSuffixPanelRight = new HorizontalPanel();
    classSuffixPanelLeft.setWidth(panelWidthLeft);
    classSuffixPanelLeft.add(new HTML("<b>" + GuiFactory.strings.classSuffix() + "</b>"));
    classSuffixPanelRight.setWidth(panelWidthRight);
    classSuffixPanelRight.add(classSuffixTextBox);
    classSuffixPanelRight.add(new HTML(GuiFactory.strings.classDefaultSuffix()));   
    classSuffixPanel.add(classSuffixPanelLeft);
    classSuffixPanel.add(classSuffixPanelRight);   
    codeGenerationPanel.add(classSuffixPanel);
    
    // source for class names
    HorizontalPanel classNamePanel = new HorizontalPanel();
    classNamePanel.setHeight(panelHeight);
    HorizontalPanel classNamePanelLeft = new HorizontalPanel();
    HorizontalPanel classNamePanelRight = new HorizontalPanel();
    classNamePanelLeft.setWidth(panelWidthLeft);
    classNamePanelLeft.add(new HTML("<b>" + GuiFactory.strings.className() + "</b>"));
    classNamePanelRight.setWidth(panelWidthRight);
    VerticalPanel radioPanel = new VerticalPanel();    
    radioPanel.add(useEndpointAsNameRadio);
    radioPanel.add(useParameterAsNameRadio);
    classNamePanelRight.add(radioPanel);       
    classNamePanel.add(classNamePanelLeft);
    classNamePanel.add(classNamePanelRight);   
    codeGenerationPanel.add(classNamePanel);
    
    // source for class names
    HorizontalPanel indentionPanel = new HorizontalPanel();
    indentionPanel.setHeight(panelHeight);
    HorizontalPanel indentionPanelLeft = new HorizontalPanel();
    HorizontalPanel indentionPanelRight = new HorizontalPanel();
    indentionPanelLeft.setWidth(panelWidthLeft);
    indentionPanelLeft.add(new HTML("<b>" + GuiFactory.strings.indentionStyle() + "</b>"));
    indentionPanelRight.setWidth(panelWidthRight);
    VerticalPanel indentionRadioPanel = new VerticalPanel();
    indentionRadioPanel.add(indentWithSpacesRadio);    
    indentMiniPanel.add(indentWidthTextBox);
    indentMiniPanel.add(new HTML(GuiFactory.strings.indentionWidth()));
    indentionRadioPanel.add(indentMiniPanel);
    indentionRadioPanel.add(indentWithTabsRadio);
    indentionPanelRight.add(indentionRadioPanel);       
    indentionPanel.add(indentionPanelLeft);
    indentionPanel.add(indentionPanelRight);   
    codeGenerationPanel.add(indentionPanel);
    
    // use separation character
    HorizontalPanel useSeparationCharacterPanel = new HorizontalPanel(); 
    useSeparationCharacterPanel.setHeight(panelHeight);
    HorizontalPanel useSeparationCharacterPanelLeft = new HorizontalPanel();
    HorizontalPanel useSeparationCharacterPanelRight = new HorizontalPanel();   
    useSeparationCharacterPanelLeft.setWidth(panelWidthLeft);
    useSeparationCharacterPanelLeft.add(new HTML("<b>" + GuiFactory.strings.sepChar() + "</b>"));
    useSeparationCharacterPanelRight.setWidth(panelWidthRight);
    VerticalPanel miniSepPanel = new VerticalPanel();    
    HorizontalPanel miniSepCheckPanel = new HorizontalPanel();
    miniSepPanel.add(miniSepCheckPanel);
    miniSepCheckPanel.add(useSeparationCharacterCheckBox);
    miniSepCheckPanel.add(new HTML(GuiFactory.strings.useSepChar()));    
    miniSepTextPanel.add(separationCharacterTextBox);
    miniSepTextPanel.add(new HTML(GuiFactory.strings.sepWithChar()));
    miniSepPanel.add(miniSepTextPanel);
    useSeparationCharacterPanelRight.add(miniSepPanel);    
    useSeparationCharacterPanel.add(useSeparationCharacterPanelLeft);
    useSeparationCharacterPanel.add(useSeparationCharacterPanelRight);   
    codeGenerationPanel.add(useSeparationCharacterPanel);
    
    tabPanel.add(generalPanel, "<a href=\"#\">" + GuiFactory.strings.generalTab() + "</a>", true);
    tabPanel.add(preferencesPanel, "<a href=\"#\">" + GuiFactory.strings.preferencesTab() + "</a>", true);
    tabPanel.add(requestPanel, "<a href=\"#\">" + GuiFactory.strings.requestTab() + "</a>", true);
    tabPanel.add(codeGenerationPanel, "<a href=\"#\">" + GuiFactory.strings.codeGenerationTab() + "</a>", true);
    tabPanel.selectTab(0);
       
    // ok button
    HorizontalPanel buttonPanel = new HorizontalPanel();
    Button okButton = new Button(GuiFactory.strings.ok());
    buttonPanel.add(okButton);
    okButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        // apply changes
        alwaysShowDetails = alwaysShowDetailsTemp;
        treeItemsAlwaysOpen = treeItemsAlwaysOpenTemp;
        useSeparationCharacter = useSeparationCharacterTemp;        
        RestCompilePanel.generateCode(CodeGenerator.language);
        GuiFactory.blockScreen(false);       
        dialogBox.hide();
      }
    });
     
    // cancel button
    Button closeButton = new Button(GuiFactory.strings.cancel());
    buttonPanel.add(closeButton);
    closeButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {    
        GuiFactory.blockScreen(false);
        dialogBox.hide();
      }
    });
     
    settingsPanel.add(new HTML("<br />"));
    settingsPanel.add(tabPanel);
    settingsPanel.add(new HTML("<br />"));
    settingsPanel.add(buttonPanel);
    settingsPanel.setCellHorizontalAlignment(buttonPanel, HasHorizontalAlignment.ALIGN_CENTER);
     
    dialogBox.setPopupPosition((int) Math.floor(Window.getClientWidth() / 4), (int) Math.floor(Window.getClientHeight() / 4));
    dialogBox.setWidget(settingsPanel);   
    GuiFactory.blockScreen(true);    
    dialogBox.show();   
  }
 
  private static void updateAndDisplayConfirmLink(String selectedLanguage, HTML confirmLink, HorizontalPanel confirmLangChange) {
    confirmLangChange.setVisible(true);
    confirmLink.setHTML("");
    if (selectedLanguage.equals(GuiFactory.strings.german())) {      
      confirmLink.setHTML(confirm_de);
    }
    else if (selectedLanguage.equals(GuiFactory.strings.english_US())) {
      confirmLink.setHTML(confirm_enUS);
    }
    else if (selectedLanguage.equals(GuiFactory.strings.catalan())) {
      confirmLink.setHTML(confirm_ca);
    }    
  }
} public class SyntaxHighlighter {
	public SyntaxHighlighter() {
		return;
	}
  
  public static String toHtml(String code) {
    code = encodeEntities(code);
    
    // <openTag>
    String regExp = "(&lt;\\??\\w+)(.*?)(\\??/?&gt;)";
    code = code.replaceAll(regExp, "<span class=\"tag\">$1</span>$2<span class=\"tag\">$3</span>\n<br />");
    
    // attrib = "string"
    regExp = "([a-zA-Z0-9_:]+\\s*=)(\\s*[&quot;a-zA-Z0-9_:#\\/\\.\\-\\s\\(\\)\\+]+&quot;|[&#39;a-zA-Z0-9_:#\\/\\.\\-\\s\\(\\)\\+]+&#39;)";
    code = code.replaceAll(regExp, "<span class=\"attribute\">$1</span><span class=\"string\">$2</span>");
    
    // </closeTag>
    regExp = "(&lt;/\\w+&gt;)";
    code = code.replaceAll(regExp, "<span class=\"tag\">$1</span>\n<br />");
        
    return code;
  }
  
  public static String encodeEntities(String code) {
    code = code.replaceAll("'", "&#39;");   
    code = code.replaceAll("\"", "&quot;");   
    code = code.replaceAll("<", "&lt;");    
    code = code.replaceAll(">", "&gt;");    
    return code;
  }
  
  public static String htmlifyLineBreaksAndTabs(String code, int tabWidth) {
    code = encodeEntities(code);
    code = code.replaceAll("\n", "<br />");
    String tab = "";
    for (int i = 0; i < tabWidth; i++) tab += "&nbsp;";
    code = code.replaceAll("\t", tab);
    return code;
  }
  
  public static String highlight(String code) {    
    code = encodeEntities(code);
    // complete tag
    String regExp = "(^&lt;/?.*?&gt;$)";    
    code = code.replaceAll(regExp, "<span class=\"tag\">$1</span>");

    // opening tag    
    regExp = "(^&lt;.*?\\s)";    
    code = code.replaceAll(regExp, "<span class=\"tag\">$1</span><span class=\"attribute\">");
    
    // closing tag
    regExp = "(/?&gt;$)";    
    code = code.replaceAll(regExp, "</span><span class=\"tag\">$1</span>");    
       
    // attribute strings
    regExp = "(.*?)(&quot;(.*?&quot;)*)";
    code = code.replaceAll(regExp, "<span class=\"attribute\">$1</span><span class=\"string\">$2</span>");
    regExp = "(&#39;.*?&#39;)";
    code = code.replaceAll(regExp, "<span class=\"attribute\">$1</span><span class=\"string\">$2</span>");

    // xml comments
    regExp = "(&lt;!--?.*?--&gt;)";    
    code = code.replaceAll(regExp, "<span class=\"comment\">$1</span>");  
    
    return code;    
  }
}
 public class TypeEstimator {
  public final static String sure = "sure"; 
  public final static String supposed = "supposed";
  public final static String unsure = "unsure";
  public final static String manual = "manual";  
  
  public final static String typeString = "xsd:string";
  public final static String typeBoolean = "xsd:boolean";
  public final static String typeInteger = "xsd:integer";
  public final static String typeFloat = "xsd:float";  
  public final static String typeDateTime = "xsd:dateTime"; 
  public final static String typeTime = "xsd:time"; 
  public final static String typeDate = "xsd:date";       
  public final static String typeAnyUri = "xsd:anyURI";
  
  public final static String typeLanguage = "language";
  public final static String typeCountry = "country";
  
  private final static String regExString = ".*?\\w+.*?";
  
  private final static String regExInteger = "[0-9]+";  
  
  private final static String regExFloat = "[0-9]*[\\.|,][0-9]+";
  
  private final static String regExBoolean = "false|true|1|0|yes|no";
  // unsure if 1 or 0, check for param name is.+?, .+?ed, has.+?    
  private final static String regExBooleanParam = "^(is).+?|^(has).+?|.+?(ed)$|.+?(ok)$";    
  
  private final static String regExCountry = "AX|AF|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CD|CG|CK|CR|CI|HR|CU|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GN|GW|GY|HT|HM|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IL|IT|JM|JP|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|MS|MA|MZ|MM|NA|NR|NP|NL|AN|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|SH|KN|LC|PM|VC|WS|SM|ST|SA|SN|CS|SC|SL|SG|SK|SI|SB|SO|ZA|GS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VA|VE|VN|VG|VI|WF|EH|YE|ZM|ZW";
  private final static String regExCountryParam = "country|region|land|c.*?try.?code";
  
  private final static String regExLanguage = "aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|ca|co|cs|cy|da|de|dz|el|en|eo|es|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|he|hi|hr|hu|hy|ia|id|ie|ik|is|it|iu|ja|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|ug|uk|ur|uz|vi|vo|wo|xh|yi|yo|za|zh|zu";
  private final static String regExLanguageParam = "lang|language|hl|lr|local.?|lang.*?.?code";
  
  // 2007-01-01T12:34:56
  private final static String regExDateTime = "^([0-9]{4})-?([0-9]{2})-?([0-9]{2})T([0-9]{2}):?([0-9]{2}):?([0-9]{2})$";
  
  // 2007-01-01
  private final static String regExDate = "^([0-9]{4})-?([0-9]{2})-?([0-9]{2})$";
  
  // 12:34:56
  private final static String regExTime = "^([0-9]{2}):?([0-9]{2}):?([0-9]{2})$";
  
  // https://...
  private final static String regExAnyUri = "^(http://).*?|^(https://).*?|^(www\\.).*?";
  
  private final static String regExBooleanWeak = "1|0";
  private final static String regExBooleanStrong = "false|true|yes|no";
  
  public static String[] estimate(String value, String param) {
    String estimateQuality = unsure;
    String probableType = "";       
    
    if (value.matches(regExBoolean)) {      
      if (value.matches(regExBooleanWeak)) {
        // still believe it's int, check for param name...
        estimateQuality = supposed; 
        probableType = typeInteger;
        if (param.matches(regExBooleanParam)) {
          estimateQuality = sure; 
          probableType = typeBoolean;
        }
      }      
      else if (value.matches(regExBooleanStrong)) {
        estimateQuality = sure; 
        probableType = typeBoolean;
      }
    }
    else if (value.matches(regExInteger)) {      
      estimateQuality = sure; 
      probableType = typeInteger;
    }
    else if (value.matches(regExFloat)) {      
      estimateQuality = sure; 
      probableType = typeFloat;
    }
    else if (value.matches(regExAnyUri)) {      
      estimateQuality = sure; 
      probableType = typeAnyUri;
    }    
    else if (value.matches(regExDateTime)) {      
      estimateQuality = sure; 
      probableType = typeDateTime;
    }    
    else if (value.matches(regExDate)) {      
      estimateQuality = sure; 
      probableType = typeDate;
    }
    else if (value.matches(regExTime)) {      
      estimateQuality = sure; 
      probableType = typeTime;
    }    
    else if (value.matches(regExCountry)) {
      estimateQuality = supposed;
      probableType = typeCountry;
      if (param.matches(regExCountryParam)) {      
        estimateQuality = sure;
        probableType = typeCountry;
      }
    }
    else if (value.matches(regExLanguage)) {
      estimateQuality = supposed;
      probableType = typeLanguage;
      if (param.matches(regExLanguageParam)) {
        estimateQuality = sure;
        probableType = typeLanguage;
      }
    }
    else if (value.matches(regExString)) {
      probableType = typeString;
      estimateQuality = supposed;
    }   
    else {
      estimateQuality = unsure;
    }
    String[] estimate = {probableType, estimateQuality};
    return estimate;    
  }
}
 public class Uri {
  private String scheme = "", authority = "", path = "", query = "", fragment = "";
  
  /*
   *   foo://example.com:8042/over/there?name=ferret#nose
   *   \ /   \______________/\_________/ \_________/ \__/
   *    |           |             |           |        |
   *  scheme    authority       path        query   fragment
   * 
   */
  
  public Uri(String uriString) {   
    resolve(uriString);
  }
  
  private void resolve(String uriString) {
    try {
      // INPUT: http://whatever.com/some/path?some=query#someFragment
      // scheme
      int marker = uriString.indexOf("://");    
      if (marker > 0) {
        scheme = uriString.substring(0, marker);
        uriString = uriString.substring(marker + 3);
      }
      else {
        throw new InvalidUriException(GuiFactory.strings.invalidUri());   
      }
      
      // INPUT: whatever.com/some/path?some=query#someFragment
      // authority
      marker = uriString.indexOf("/");     
      if (marker > 0) {
        // whatever.com/...
        authority = uriString.substring(0, marker);      
      }
      // whatever.com 
      else {
        authority = uriString;
        return;
      }        
      uriString = uriString.substring(marker + 1);
      
      // INPUT: some/path?some=query#someFragment
      // path                  
      marker = uriString.indexOf("?");
      // some/path?...
      if (marker > 0) {  
        path = uriString.substring(0, marker);
        uriString = uriString.substring(marker);
      }
      else if (marker == -1) {
        // some/path#...
        marker = uriString.indexOf("#");
        if (marker > 0) {      
          path = uriString.substring(0, marker);
          uriString = uriString.substring(marker);
        }    
        else if (marker == -1) {
          // some/path/ or some/path
          path = uriString;        
          return;
        }
      }
      
      // INPUT: ?some=query#someFragment
      // query    
      marker = uriString.indexOf("#");    
      if (marker > 0) {
        // ?some=query#...
        query = uriString.substring(1, marker);
        uriString = uriString.substring(marker);
      }
      else if (marker == -1) {
        // ?some=query
        query = uriString.substring(1);
        return;
      }   
      
      // INPUT: #someFragment
      // fragment
      fragment = uriString.substring(1);
    } catch (InvalidUriException e) {      
    }
  }

  public String getScheme() {    
    return scheme;
  }

  public String getAuthority() {
    if (!authority.endsWith("/")) {
      return authority + "/";
    }
    return authority;
  }  
  
  public String getPath() {    
    return path;
  }
  
  public String getQuery() {
    if (query.startsWith("&")) return query.substring(1);
    else return query;
  }  
  
  public String getFragment() {    
    return fragment;
  }  
  
  public String[] getPathComponents() {    
    String[] pathComponents = this.getPath().split("/");
    if (pathComponents[0].length() == 0) {
      String[] newPathComponents = new String[pathComponents.length - 1];
      for (int i = 1; i < pathComponents.length; i++) {
        newPathComponents[i] = pathComponents[i];
      }
      pathComponents = newPathComponents;
    }
    return pathComponents;
  }
  
  public String[] getQueryParameters() {
    String[] queryParameters = this.getQuery().split("&");
    // this deals with the http://www.bla.com/bla?&var=param case ('?' followed immediately by '&')
    if (queryParameters[0].length() == 0) {
      String[] newQueryParameters = new String[queryParameters.length - 1];
      for (int i = 1; i < queryParameters.length; i++) {
        newQueryParameters[i] = queryParameters[i];
      }
      queryParameters = newQueryParameters;
    }
    for (int i = 0; i < queryParameters.length; i++) {      
      if (queryParameters[i].indexOf("=") > 0) {
        queryParameters[i] = queryParameters[i].substring(0, queryParameters[i].indexOf("="));
      }
      else {
        queryParameters[i] = "";
      }
    }
    return queryParameters;
  }
  
  public String[] getQueryValues() {
    String[] queryValues = this.getQuery().split("&");
    if (queryValues[0].length() == 0) {
      String[] newQueryValues = new String[queryValues.length - 1];
      for (int i = 1; i < queryValues.length; i++) {
        newQueryValues[i] = queryValues[i];
      }
      queryValues = newQueryValues;
    }
    for (int i = 0; i < queryValues.length; i++) {
      if (queryValues[i].indexOf("=") >= 0) {
        queryValues[i] = queryValues[i].substring(queryValues[i].indexOf("=") + 1);
      }
      else {        
        queryValues[i] = queryValues[i];
      }
    }
    return queryValues;
  }  
  
  public String toString() {
    String uriString = scheme + "://" + authority + "/";
    if (path.length() > 0) uriString += path;
    if (query.length() > 0) uriString += "?" + query;
    if (fragment.length() > 0) uriString += "#" + fragment;    
    return uriString;
  }

  public String getEndpoint() {
    String endpoint = scheme + "://" + authority;
    String[] pathCompontents = this.getPathComponents();
    for (int i = 0; i < pathCompontents.length - 1; i++) {
      endpoint += "/" + pathCompontents[i];
    }
    return endpoint;
  }

  public String getRequest() {
    String[] pathCompontents = this.getPathComponents();
    if (pathCompontents.length > 0) {
      return pathCompontents[pathCompontents.length - 1];
    }
    else {
      return "";
    }
  }  
}
 public class Analyzer {
  public static ApplicationNode application;
  private String requestString = "";
  private String referenceParamSuffix = "Param";  
  public static final String sampleValueHeader = " (Sample Value: ";
  public static final String sampleValueFooter = ")";
  public static final String templateParamOpenChar = "{";
  public static final String templateParamCloseChar = "}";
  public static final String templateParamRegExp = "^.*?(\\" + templateParamOpenChar + "(.+?)\\" + templateParamCloseChar + ")+.*?$";  
    
  /**
   * 
   */
  public Analyzer(String request) {
    this.requestString = request;
    return;
  }
  
  public String getRequestString() {
    return this.requestString; 
  } 

  public void setApplication(ApplicationNode applicationNode) {
    application = applicationNode;    
  }
    
  public ApplicationNode analyze() {
    Uri uri = new Uri(requestString.substring(requestString.indexOf(" ") + 1));
    
    String[] queryParameters = uri.getQueryParameters();
    String[] queryValues = uri.getQueryValues();
    String[] pathComponents = uri.getPathComponents();
        
    // <application>
    setApplication(new ApplicationNode(this));    
    
    // <resources>
    ResourcesNode resources = null;
    String base = uri.getScheme() + "://" + uri.getAuthority();
    if (application.getResources() == null) {
      resources = new ResourcesNode(base, application);
      application.addResources(resources);
    }
    else {
      resources = application.getResources();
      resources.updateBase(resources.getBase(), base);
    }    
    if ((pathComponents == null) || (pathComponents.length == 0)) return application; 
    
    // <resource> child of <resources>
    ResourceNode resource = new ResourceNode(pathComponents[0], resources, application);    
    if (!resources.addResource(resource)) {
      // share the already existing resource 
      resource = resources.getResourceByPath(pathComponents[0]);
    } 
    // check for potential necessary template parameters
    checkForTemplateParams(resource);
    
    // <resource> of other <resource>
    for (int i = 1; i < pathComponents.length; i++) {           
      ResourceNode newResource = new ResourceNode(pathComponents[i], resource, application);     
      if (!resource.addResource(newResource)) {      
        // share the already existing resource
        resource = resource.getResourceByPath(pathComponents[i]);        
      }
      else {
        // the new resource is not yet contained
        resource = newResource;
      }
      // check for potential necessary template parameters
      checkForTemplateParams(resource);
    }
    
    // <method>   
    String internalMethodId = "";
    for(int i = 0; i < queryParameters.length; i++) {
      internalMethodId += queryParameters[i];
    }
    ListBox httpMethodListBox = ReferenceManager.getHttpMethodListBox(requestString);
    String httpMethod = httpMethodListBox.getItemText(httpMethodListBox.getSelectedIndex());    
    MethodNode method = new MethodNode(httpMethod, resource, application);    
    if (!resource.addMethod(method)) {
      // share the already existing method, however reanalyze the request params      
      method = resource.getMethodByInternalId(internalMethodId); 
      method.getRequest().getAllParams().clear();
    }
    // make sure that even when recycling an old method the http method is correct
    method.updateName(method.getName(), httpMethod); 
    
    // <request>
    RequestNode request = new RequestNode(method, application);
    method.addRequest(request);
    
    // <param>
    for(int i = 0; i < queryParameters.length; i++) {
      String name = queryParameters[i];      
      String style = ParamItem.query;
      String[] typeEstimate = TypeEstimator.estimate(queryValues[i], queryParameters[i]);
      String type = typeEstimate[0];
      String estimateQuality = typeEstimate[1];
      boolean isRequired = false;
      boolean isRepeating = false; 
      String fixedValue = "";
      String path = "";
      String defaultValue = "";
      String value = queryValues[i];
      
      ParamNode param = new ParamNode(name, type, estimateQuality, style, isRequired, isRepeating, defaultValue, fixedValue, path, value, request, application);
      ApplicationNode.addPotentiallyToBeSharedParam(param);
      DocNode docNode;
      if (queryValues[i].length() > 0) {
        docNode = new DocNode("en", name + sampleValueHeader + queryValues[i] + sampleValueFooter, "", param);
      }
      else {
        docNode = new DocNode("en", name, "", param);
      }
      param.addDoc(docNode);
      request.addParam(param);      
    }
    if (application.getParamsToBeShared().size() > 0) {
      optimizeByOutsourcing();
    }
    return application;
  }

  /**
   * @return
   */
  private void optimizeByOutsourcing() {
    Vector paramsToBeShared = application.getParamsToBeShared();
    Vector usedIds = new Vector();
    for(Iterator i = paramsToBeShared.iterator(); i.hasNext(); /* empty */) {
      ParamNode param = (ParamNode) i.next();
      String id = param.getName() + referenceParamSuffix;
      if (usedIds.contains(id)) {
        int j = 1;
        while(usedIds.contains(id + j)) {
          // empty
        }
        id = id + j;
      }      
      usedIds.add(id);
      param.setId(id);
      application.addParam(param);
      replaceParamByReferenceParam(application.getResources(), param);
    }
  }

  /**
   * @param param
   */
  private void replaceParamByReferenceParam(GenericNode parent, ParamNode param) {
    Vector allResources = null;
    if (parent instanceof ResourcesNode) {
      allResources = ((ResourcesNode) parent).getAllResources();
    }
    else if (parent instanceof ResourceNode) {
      allResources = ((ResourceNode) parent).getAllResources();
    } 
    for (Iterator i = allResources.iterator(); i.hasNext(); /* empty */) {
      ResourceNode resource = (ResourceNode) i.next();
      if (resource.getAllMethods() != null) {
        Vector allMethods = resource.getAllMethods();
        for (Iterator j = allMethods.iterator(); j.hasNext(); /* empty */) {
          MethodNode method = (MethodNode) j.next();
          if (method.getRequest() != null) {
            RequestNode request = method.getRequest();
            if (request.getAllParams() != null) {
              Vector allParams = request.getAllParams();
              int paramIndex = 0;
              for(Iterator k = ((Vector) allParams.clone()).iterator(); k.hasNext(); /* empty */) {
                ParamNode p = (ParamNode) k.next();
                if (p.getName().equals(param.getName()) &&
                    p.getValue().equals(param.getValue())) {                  
                  request.removeParam(p);                  
                  ParamNode referenceParam = new ParamNode(param.getName(), request, application);
                  referenceParam.setHref("#" + param.getId());
                  request.insertParamAt(referenceParam, paramIndex);                  
                }
                paramIndex++;
              }
            }  
          }        
        }
      }
      replaceParamByReferenceParam(resource, param);
    }
  }
  
  /**
   * @param resource
   */
  private void checkForTemplateParams(ResourceNode resource) {
    // check if we have a template path like /shop/{cartId}/      
    if (resource.getPath().matches(templateParamRegExp)) {     
      String path = resource.getPath();        
      int indexOfOpen = path.indexOf(templateParamOpenChar);
      int indexOfClose = path.indexOf(templateParamCloseChar);        
      while(indexOfOpen >= 0 &&
          indexOfClose > 0 &&
          indexOfOpen < indexOfClose) {          
        String templateParamName = path.substring(indexOfOpen + 1, indexOfClose);          
        ParamNode templateParam = new ParamNode(
            templateParamName,
            TypeEstimator.typeString,            
            ParamItem.template,
            resource,
            application);
        resource.addParam(templateParam);
        path = path.substring(indexOfClose + 1);
        indexOfOpen = path.indexOf(templateParamOpenChar);
        indexOfClose = path.indexOf(templateParamCloseChar);
      }        
    }    
  }

  /**
   * @param request
   */
  public void setRequestString(String request) {
    requestString = request;    
  }
}
 public class ApplicationNode extends GenericNode {
  // each new <application> node shares the already existing <resources> node
  private static ResourcesNode resources;
  // each new <application> node shares the already existing <grammars> node
  public static GrammarsNode grammars;
  // each new <application> node shares the already existing @extNs attributes
  private static Vector allNamespaces = new Vector();
  // each new <application> node shares the already existing <fault> nodes
  private Vector allFaults = new Vector();
  // each new <application> node shares the already existing <method> nodes
  private static Vector allMethods = new Vector();
  // each new <application> node shares the already existing <method> nodes
  private static Vector allRepresentations = new Vector();
  // each new <application> node shares the already existing <param> nodes
  private static Vector allParams = new Vector();
  // each new <application> node shares the already existing <resource_type> nodes
  private static Vector allResourceTypes = new Vector();
  private static Vector paramsPotentiallyToBeShared = new Vector();
  private static Vector paramsToBeShared = new Vector();
  private Analyzer analyzer;
    
  public ApplicationNode(Analyzer requestAnalyzer) {
    analyzer = requestAnalyzer;
    return;
  }  
  
  public Vector getParamsToBeShared() {
    return paramsToBeShared;
  }
  
  public Analyzer getAnalyzer() {
    return analyzer;
  }
  
  public GrammarsNode getGrammars() {    
    return grammars;
  }
  
  public ResourcesNode getResources() {
    return resources;     
  }
  
  public void addGrammars(GrammarsNode grammarsNode) {
    grammars = grammarsNode;
  }
  
  public void addResources(ResourcesNode resourcesNode) {    
    resources = resourcesNode;    
  }
  
  public void addNamespace(NamespaceAttribute namespace) {
    if (!namespaceAlreadyContained(namespace)) {
      allNamespaces.add(namespace);
    }
  }
  
  public static void addPotentiallyToBeSharedParam(ParamNode param) {
    for(Iterator i = paramsPotentiallyToBeShared.iterator(); i.hasNext(); /* empty */) {
      ParamNode p = (ParamNode) i.next();
      if (p.getName().equals(param.getName()) &&
          p.getValue().equals(param.getValue())) {
        addToBeSharedParam(param);
      }      
    }
    paramsPotentiallyToBeShared.add(param);
  }
  
  /**
   * @param param
   */
  private static void addToBeSharedParam(ParamNode param) {
    for(Iterator i = paramsToBeShared.iterator(); i.hasNext(); /* empty */) {
      ParamNode p = (ParamNode) i.next();
      if (p.getName().equals(param.getName()) &&
          p.getValue().equals(param.getValue())) {
        return;
      }      
    }
    paramsToBeShared.add(param);    
  }

  private boolean namespaceAlreadyContained(NamespaceAttribute namespaceToCheck) {
    Iterator namespaceIterator = allNamespaces.iterator();
    while(namespaceIterator.hasNext()) {
      NamespaceAttribute namespace = (NamespaceAttribute) namespaceIterator.next();
      if (namespace.getValue().equals(namespaceToCheck.getValue())) {
        return true;
      }
    }
    return false;
  }
  
  public void removeNamespace(String namespaceValue) {
    Iterator allNamespacesIterator = allNamespaces.iterator();
    while(allNamespacesIterator.hasNext()) {
      NamespaceAttribute namespace = (NamespaceAttribute) allNamespacesIterator.next();
      if (namespace.getValue().equals(namespaceValue)) {
        allNamespaces.remove(namespace);
        break;
      }
    }
  }
  
  public Vector getAllNamespaces() {
    return allNamespaces;
  }

  public void updateNamespace(String oldNamespace, String newNamespace) {
    Iterator allNamespacesIterator = allNamespaces.iterator();
    while(allNamespacesIterator.hasNext()) {
      NamespaceAttribute namespace = (NamespaceAttribute) allNamespacesIterator.next();
      if (namespace.getValue().equals(oldNamespace)) {
        namespace.setValue(newNamespace);        
        break;
      }
    }
  }
  
  public void addParam(ParamNode param) {    
    if (!allParams.contains(param)) {
      allParams.add(param);
    }
  }
  
  public Vector getAllParams() {    
    return allParams;
  }

  public void removeParam(ParamNode param) {
    if (allParams.contains(param)) {
      allParams.remove(param);
    }    
  }
  
  public void removeFault(FaultNode fault) {
    if (allFaults.contains(fault)) {
      allFaults.remove(fault);
    }    
  }
  
  public void addFault(FaultNode fault) {
    if (!allFaults.contains(fault)) {
      allFaults.add(fault);
    }
  }

  public Vector getAllFaults() {    
    return allFaults;
  }
  
  public void addRepresentation(RepresentationNode representation) {    
    if (!allRepresentations.contains(representation)) {
      allRepresentations.add(representation);
    }
   }
  
  public Vector getAllRepresentations() {    
    return allRepresentations;
  }

  public void removeRepresentation(RepresentationNode representation) {
    if (allRepresentations.contains(representation)) {
      allRepresentations.remove(representation);
    }    
  }

  /**
   * Resets the current application node
   */
  public void reset() {    
    if (paramsPotentiallyToBeShared != null) {
      paramsPotentiallyToBeShared.clear();
    }
    if (paramsToBeShared != null) {
      paramsToBeShared.clear();
    }    
    if (allResourceTypes != null) {
      allResourceTypes.clear();
    }
    if (allNamespaces != null) {
      allNamespaces.clear();
    }
    if (allMethods != null) {
      allMethods.clear();
    }
    if (allParams != null) {
      allParams.clear();
    }    
    if (allFaults != null) {
      allFaults.clear();
    }
    if (allRepresentations != null) {
      allRepresentations.clear();
    }
    if (resources != null) {
      resources.getAllResources().clear();
      resources.updateBase(resources.getBase(), "");
    }
    if (grammars != null) {
      grammars.getAllIncludes().clear();
    }
  }

  public Vector getAllMethods() {
    return allMethods;
  }
  
  public boolean addMethod(MethodNode method) {
    if (!alreadyContainesMethod(allMethods, method.getInternalMethodId())) {
      allMethods.add(method);      
      return true;
    }
    else {
      return false;
    }
  }
  
  public void directlyAddMethod(MethodNode method) {    
    allMethods.add(method);    
  }

  public void removeMethod(MethodNode method) {
    if (allMethods.contains(method)) {
      allMethods.remove(method);
    }    
  }
  
  public static boolean alreadyContainesMethod(Vector allMethods, String internalMethodId) {
    if (internalMethodId == null) {
      return false;
    }
    Iterator allMethodsIterator = allMethods.iterator();
    while (allMethodsIterator.hasNext()) {
      MethodNode method = (MethodNode) allMethodsIterator.next();
      if (method.getInternalMethodId() == null) {
        continue;
      }
      if (method.getInternalMethodId().equals(internalMethodId)) {
        return true;
      }
    }
    return false;
  }

  /**
   * @return
   */
  public Vector getAllResourceTypes() {    
    return allResourceTypes;
  }
  
  public void addResourceType(ResourceTypeNode resourceType) {    
    allResourceTypes.add(resourceType);
  }
  
  public void removeResourceType(ResourceTypeNode resourceType) {
    if (allResourceTypes.contains(resourceType)) {
      allResourceTypes.remove(resourceType);
    }
  }

  /**
   * 
   */
  public void removeResources() {
    resources = null;    
  }

  /**
   * 
   */
  public void removeGrammars() {
    grammars = null;    
  }
}
 public class FaultNode extends FaultRepSuperNode {
  
  public FaultNode(String faultMediaType, String faultElement, String faultProfile, String faultStatus, GenericNode parent, ApplicationNode application) {
    super(parent, application);
    super.mediaType = faultMediaType;
    super.element = faultElement;
    super.profile = faultProfile;
    super.status = faultStatus;    
  }
  
  public FaultNode(String faultStatus, GenericNode parent, ApplicationNode application) {
    super(parent, application);
    mediaType = "";
    element = "";
    profile = "";
    status = faultStatus;    
  }
  
  public FaultNode(String id, boolean isReferenced, GenericNode parent, ApplicationNode application) {
    super(parent, application, id);
    mediaType = "";
    element = "";
    profile = "";    
  }
} public class GenericNode {
  private Vector doc = new Vector();
  protected GenericNode parent;
  protected ApplicationNode application;
  
  public void addDoc(DocNode docNode) {
    doc.add(docNode);
  }
  
  public Vector getAllDocs() {
    return doc;
  }
  
  public GenericNode getParent() {
    return parent;
  }
  
  public ApplicationNode getApplication() {
    return application;
  }
}
 public class ParamNode extends GenericNode {
  private String name;  
  private String type;
  private String estimateQuality; 
  private String style;
  private String id;
  private String href;
  private boolean isRequired;
  private boolean isRepeating;
  private String defaultValue;
  private String fixedValue;
  private String value;
  private String path;
  private Vector options = new Vector();
  private Vector allLinks = new Vector();
  
  public ParamNode(String paramName, String paramType, String typeEstimateQuality, String paramStyle, boolean paramIsRequired, boolean paramIsRepeating, String paramDefaultValue, String paramFixedValue, String paramPath, String paramValue, GenericNode parent, ApplicationNode application) {
    name = paramName;    
    type = paramType;
    estimateQuality = typeEstimateQuality;
    style = paramStyle;
    href = null;
    isRequired = paramIsRequired;
    isRepeating = paramIsRepeating;
    defaultValue = paramDefaultValue;
    fixedValue = paramFixedValue;   
    path = paramPath;
    value = paramValue;
    super.parent = parent;
    super.application = application;
  }

  public ParamNode(String paramName, GenericNode parent, ApplicationNode application) {
    name = paramName;    
    type = TypeEstimator.typeString;
    estimateQuality = TypeEstimator.manual;
    style = ParamItem.query;
    isRequired = false;
    isRepeating = false;
    href = null;
    defaultValue = "";
    fixedValue = "";
    path = "";
    value = GuiFactory.strings.paramValue();
    super.parent = parent;
    super.application = application;
  }
  
  public ParamNode(String paramId, boolean isReferenced, GenericNode parent, ApplicationNode application) {
    id = null;    
    href = "#" + paramId;
    type = "";
    estimateQuality = "";
    style = "";
    isRequired = false;
    isRepeating = false;
    defaultValue = "";
    fixedValue = "";
    path = "";
    value = "";
    super.parent = parent;
    super.application = application;
  }

  /**
   * This is a template parameter constructor for resources with a path like .../shop/{cartId}/...
   * @param templateParamName
   * @param typeString
   * @param template
   * @param resource
   * @param application
   */
  public ParamNode(String templateParamName, String typeString, String template, ResourceNode resource, ApplicationNode application) {
    name = templateParamName;
    type = typeString;
    style = template;
    estimateQuality = "";
    defaultValue = "";
    fixedValue = "";
    path = "";
    super.parent = resource;
    super.application = application;
  }

  public String getName() {
    return name;    
  }
  
  public String getId() {
    return id;
  }
 
  public String getPath() {
    return path;    
  }
  
  public String getValue() {
    return value;
  }
  
  public String getType() {
    return type;
  }
  
  public String getEstimateQuality() {
    return estimateQuality;
  }
  
  public void setEstimateQuality(String quality) {
    estimateQuality = quality;
  }
  
  public String getStyle() {
    return style;
  }
  
  public boolean getIsRequired() {
    return isRequired;
  }
  
  public String getDefaultValue() {
    return defaultValue;
  }
  
  public String getFixedValue() {
    return fixedValue;
  }
  
  public boolean getIsRepeating() {
    return isRepeating;
  }

  public void updateName(String oldName, String newName) {
    if (oldName.equals(getName())) {
      name = newName;
    }
  }
 
  public void updateId(String oldId, String newId) {
    if (oldId.equals(getId())) {
      id = newId;      
    }
  }
  
  public void updateType(String oldType, String newType) {
    if (oldType.equals(getType())) {
      type = newType;
      estimateQuality = TypeEstimator.manual;
    }
  }
  
  public void updatePath(String oldPath, String newPath) {
    if (oldPath.equals(getPath())) {
      path = newPath;
      estimateQuality = TypeEstimator.manual;
    }
  }
  
  public void updateDefaultValue(String oldDefaultValue, String newDefaultValue) {
    if (oldDefaultValue.equals(getDefaultValue())) {
      defaultValue = newDefaultValue;
    }
  }
  
  public void updateFixedValue(String oldFixedValue, String newFixedValue) {
    if (oldFixedValue.equals(getFixedValue())) {
      fixedValue = newFixedValue;
    }
  }
  
  public void updateStyle(String oldStyle, String newStyle) {
    if (oldStyle.equals(getStyle())) {
      style = newStyle;
    }
  }
  
  public void updateIsRequired(boolean oldIsRequired, boolean newIsRequired) {
    if (oldIsRequired == getIsRequired()) {
      isRequired = newIsRequired;
    }
  }
  
  public void updateIsRepeating(boolean oldIsRepeating, boolean newIsRepeating) {
    if (oldIsRepeating == getIsRepeating()) {
      isRepeating = newIsRepeating;
    }
  }

  public Vector getOptions() {    
    return options ;
  }

  public void setOptions(Vector optionValues) {
    options = optionValues;   
  }

  public void addOption(String option) {
    if (!options.contains(option)) {
      options.add(option);
    }
  }
  
  /**
   * @return
   */
  public Vector getAllLinks() {    
    return allLinks;
  }

  /**
   * @return
   */
  public String getHref() {
    return href;
  }

  /**
   * @param nodeValue
   */
  public void setId(String newId) {
    id = newId;    
  }

  /**
   * @param string
   */
  public void setHref(String href) {
    this.href = href;    
  }  
}
 public class RepresentationNode extends FaultRepSuperNode {
  
  public RepresentationNode(String representationMediaType, String representationElement, String representationProfile, String representationStatus, GenericNode parent, ApplicationNode application) {
    super(parent, application);
    super.mediaType = representationMediaType;
    super.element = representationElement;
    super.profile = representationProfile;
    super.status = representationStatus;    
  }
  
  public RepresentationNode(String representationElement, String mediaType, GenericNode parentNode, ApplicationNode application) {
    super(parentNode, application);
    super.mediaType = mediaType;
    super.element = representationElement;
    super.profile = "";   
    super.status = "";
  }

  public RepresentationNode(String id, boolean isReferenced, GenericNode parentNode, ApplicationNode application) {
    super(parentNode, application, id);
    super.mediaType = "";
    super.element = "";
    super.profile = "";        
  } 
} public class RequestNode extends GenericNode {
  private Vector allParams = new Vector();
  private Vector allRepresentations = new Vector();
  
  public RequestNode(MethodNode method, ApplicationNode application) {
    super.parent = method;
    super.application = application;
  }

  public void addParam(ParamNode param) {    
    if (!allParams.contains(param)) {
      allParams.add(param);
    }
  }
  
  public void insertParamAt(ParamNode param, int index) {
    allParams.insertElementAt(param, index);
  }
  
  public Vector getAllParams() {    
    return allParams;
  }

  public void removeParam(ParamNode param) {
    if (allParams.contains(param)) {
      allParams.remove(param);
    }    
  }

  public void addRepresentation(RepresentationNode representation) {    
    if (!allRepresentations.contains(representation)) {
      allRepresentations.add(representation);
    }
   }
  
  public Vector getAllRepresentations() {    
    return allRepresentations;
  }

  public void removeRepresentation(RepresentationNode representation) {
    if (allRepresentations.contains(representation)) {
      allRepresentations.remove(representation);
    }    
  }
}
 public class ResourceNode extends GenericNode {
  private Vector allParams = new Vector();
  private Vector allMethods = new Vector();
  // resource nodes can contain resources
  private Vector allResources = new Vector();
  private String path;
  private String id;
  private String href;
  private String absolutePath = "";
    
  public ResourceNode(String resourcePath, GenericNode parentNode, ApplicationNode application) {
    path = resourcePath;
    super.parent = parentNode;
    super.application = application;
    
    // here we need to take care whether the parent node is a <resource> or <resources> element
    ResourceNode copyOfMyself = this;
    while (copyOfMyself.getParent() instanceof ResourceNode) {      
      absolutePath = ((ResourceNode) copyOfMyself.getParent()).getPath() + "/" + absolutePath;
      copyOfMyself = (ResourceNode) copyOfMyself.getParent();
    }    
    if (copyOfMyself.getParent() instanceof ResourcesNode) {      
      absolutePath =  ((ResourcesNode) copyOfMyself.getParent()).getBase() + absolutePath;
    }
  }
  
  /**
   * @param nodeValue
   * @param isReferenced
   * @param node
   * @param application
   */
  public ResourceNode(String resourceId, boolean isReferenced, GenericNode parentNode, ApplicationNode application) {
    id = null;
    href = "#" + resourceId;
    super.parent = parentNode;
    super.application = application;
  }

  public String getPath() {
    return path;
  }
  
  public void addParam(ParamNode param) {
    Iterator allParamsIterator = allParams.iterator();
    while(allParamsIterator.hasNext()) {
      ParamNode parameter = (ParamNode) allParamsIterator.next();
      if (param.getName().equals(parameter.getName())) {
        // the param to be inserted is already contained
        return;
      }
    }    
    allParams.add(param);
  }
  
  public void updatePath(String oldPath, String newPath) {
    if (getPath().equals(oldPath)) {
      path = newPath;
    }
  }
  
  public Vector getAllParams() {    
    return allParams;
  }
  
  public void removeParam(ParamNode param) {
    if (allParams.contains(param)) {
      allParams.remove(param);
    }    
  }

  public Vector getAllMethods() {
    return allMethods;
  }
  
  public boolean addMethod(MethodNode method) {    
    if (!ApplicationNode.alreadyContainesMethod(allMethods, method.getInternalMethodId())) {
      allMethods.add(method);
      return true;
    }
    else {
      return false;
    }
  }

  public void directlyAddMethod(MethodNode method) {    
    allMethods.add(method);    
  }
  
  public void removeMethod(MethodNode method) {    
    if (allMethods.contains(method)) {
      allMethods.remove(method);
    }    
  }
  
  public Vector getAllResources() {
    return allResources;
  }
  
  public boolean alreadyContainesResource(String path) {       
    Iterator allResourcesIterator = allResources.iterator();
    while (allResourcesIterator.hasNext()) {
      ResourceNode resource = (ResourceNode) allResourcesIterator.next();      
      if (resource.getPath().equals(path)) {
        return true;
      }
    }    
    return false;
  }
  
  public boolean addResource(ResourceNode resource) {    
    if (!alreadyContainesResource(resource.getPath())) {      
      allResources.add(resource);      
      return true;
    }
    else {
      return false;
    }
  }
  
  public ResourceNode getResourceByPath(String path) {
    Vector allResources = getAllResources();
    Iterator allResourcesIterator = allResources.iterator();
    while (allResourcesIterator.hasNext()) {
      ResourceNode resource = (ResourceNode) allResourcesIterator.next();      
      if (resource.getPath().equals(path)) {
        return resource;
      }
    }    
    return null;
  }
  
  public void removeResource(ResourceNode resource) {
    if (allResources.contains(resource)) {
      allResources.remove(resource);
    }
  }
  
  public void updateResources(ResourceNode oldResource, ResourceNode newResource) {
    if (allResources.contains(oldResource)) {
      allResources.remove(oldResource);
      allResources.add(newResource);
    }    
  }

  public String getAbsolutePath() {
    return absolutePath;    
  }  

  /**
   * @return
   */
  public String getId() {
    return id;
  }

  /**
   * @return
   */
  public String getHref() {    
    return href;
  }

  /**
   * @param newId
   */
  public void setId(String newId) {
    id = newId;    
  }

  public MethodNode getMethodByInternalId(String internalMethodId) {
    Iterator allMethodsIterator = allMethods.iterator();
    while (allMethodsIterator.hasNext()) {
      MethodNode method = (MethodNode) allMethodsIterator.next();
      if (method.getInternalMethodId().equals(internalMethodId)) {
        return method;
      }
    }
    return null;
  }
}
 public class ResourceTypeNode extends GenericNode {
  private String id;
  private String href;
  private Vector allParams = new Vector();
  private Vector allMethods = new Vector();
  
  /**
   * @param string
   * @param parentNode   
   */
  public ResourceTypeNode(String resourceTypeId, ApplicationNode parentNode) {
    id = resourceTypeId;
    super.parent = parentNode;    
    super.application = parentNode;
  }

  public String getId() {
    return id;
  }
  
  public String getHref() {
    return href;
  }
      
  public boolean addMethod(MethodNode method) {
    if (!ApplicationNode.alreadyContainesMethod(allMethods, method.getInternalMethodId())) {
      allMethods.add(method);
      return true;
    }
    else {
      return false;
    }
  }

  public void directlyAddMethod(MethodNode method) {    
    allMethods.add(method);    
  }
  
  public void removeMethod(MethodNode method) {    
    if (allMethods.contains(method)) {
      allMethods.remove(method);
    }    
  }

  /**
   * @return
   */
  public Vector getAllMethods() {
    return allMethods;
  }

  public void addParam(ParamNode param) {    
    if (!allParams.contains(param)) {
      allParams.add(param);
    }
  }
  
  public Vector getAllParams() {    
    return allParams;
  }

  public void removeParam(ParamNode param) {
    if (allParams.contains(param)) {
      allParams.remove(param);
    }    
  }

  public void updateId(String oldId, String newId) {
    if (oldId.equals(id)) {
      id = newId;
    }
  }
} public class ResponseNode extends GenericNode {
  private Vector allParams = new Vector();
  private Vector allRepresentations = new Vector();
  private Vector allFaults = new Vector();  

  public ResponseNode(MethodNode method, ApplicationNode application) {   
    super.parent = method;
    super.application = application;
  }
  
  public void addParam(ParamNode param) {    
   if (!allParams.contains(param)) {
     allParams.add(param);
   }
  }
    
  public Vector getAllParams() {    
    return allParams;
  }
  
  public void removeParam(ParamNode param) {
    if (allParams.contains(param)) {
      allParams.remove(param);
    }    
  }

  public void addRepresentation(RepresentationNode representation) {    
    if (!allRepresentations.contains(representation)) {
      allRepresentations.add(representation);
    }
   }
  
  public Vector getAllRepresentations() {    
    return allRepresentations;
  }

  public void removeRepresentation(RepresentationNode representation) {
    if (allRepresentations.contains(representation)) {
      allRepresentations.remove(representation);
    }    
  }

  public void removeFault(FaultNode fault) {
    if (allFaults.contains(fault)) {
      allFaults.remove(fault);
    }    
  }
  
  public void addFault(FaultNode fault) {
    if (!allFaults.contains(fault)) {
      allFaults.add(fault);
    }
  }

  public Vector getAllFaults() {    
    return allFaults;
  }
}
 public class WadlXml {
  private Document wadl = XMLParser.createDocument();
  private static final String xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
  
  // list of elements
  public static final String applicationNode = "application";  
  public static final String resourcesNode = "resources";
  public static final String resourceNode = "resource";
  public static final String resourceTypeNode = "resource_type";
  public static final String requestNode = "request";
  public static final String responseNode = "response";  
  public static final String methodNode = "method";
  public static final String paramNode = "param";
  public static final String docNode = "doc";
  public static final String grammarsNode = "grammars";
  public static final String includeNode = "include";
  public static final String representationNode = "representation";
  public static final String faultNode = "fault";
  public static final String optionNode = "option";
  public static final String linkNode = "link";
  
  // allowed child elements
  public static final String[] applicationChildren = {resourcesNode, grammarsNode, resourceTypeNode, methodNode, representationNode, paramNode, faultNode, docNode};
  public static final String[] resourcesChildren = {resourceNode, docNode};
  public static final String[] grammarsChildren = {includeNode, docNode};
  public static final String[] includeChildren = {docNode};
  public static final String[] optionChildren = {docNode};
  public static final String[] linkChildren = {docNode};
  public static final String[] resourceChildren = {paramNode, methodNode, resourceNode, docNode};
  public static final String[] resource_typeChildren = {paramNode, methodNode, docNode};
  public static final String[] methodChildren = {requestNode, responseNode, docNode};
  public static final String[] requestChildren = {representationNode, paramNode, docNode};
  public static final String[] responseChildren = {representationNode, faultNode, paramNode, docNode};
  public static final String[] representationChildren = {paramNode, docNode};
  public static final String[] paramChildren = {optionNode, linkNode, docNode};
  public static final String[] faultChildren = {paramNode, docNode};

  // list of attributes
  public static final String application_xmlns_xsi = "xmlns:xsi";
  public static final String application_xmlns_xsd = "xmlns:xsd";  
  public static final String application_xsi_schemaLocation = "xsi:schemaLocation";
  public static final String application_xmlns = "xmlns";  
  public static final String application_xmlns_extNs = "xmlns:extNs"; // for additional external namespaces
  public static final String doc_xml_lang = "xml:lang";
  public static final String doc_title = "title";
  public static final String include_href = "href";
  public static final String resources_base = "base";
  public static final String resource_href = "href";
  public static final String resource_id = "id";
  public static final String resource_path = "path";
  public static final String resource_type = "type";
  public static final String resource_queryType = "queryType";
  public static final String resource_type_id = "id";
  public static final String method_href = "href";
  public static final String method_id = "id";
  public static final String method_name = "name";
  public static final String representation_href = "href";
  public static final String representation_id = "id";
  public static final String representation_mediaType = "mediaType";
  public static final String representation_element = "element";
  public static final String representation_profile = "profile";
  public static final String representation_status = "status";
  public static final String fault_href = "href";
  public static final String fault_id = "id";
  public static final String fault_mediaType = "mediaType";
  public static final String fault_element = "element";
  public static final String fault_profile = "profile";
  public static final String fault_status = "status";
  public static final String param_id = "id";
  public static final String param_href = "href";
  public static final String param_name = "name";
  public static final String param_style = "style";
  public static final String param_type = "type";
  public static final String param_default = "default";
  public static final String param_path = "path";
  public static final String param_required = "required";
  public static final String param_repeating = "repeating";
  public static final String param_fixed = "fixed";
  public static final String option_value = "value";
  public static final String link_resource_type = "resource_type";
  public static final String link_rel = "rel";
  public static final String link_rev = "rev";
  
  // allowed attributes
  public static final String[] applicationAttributes = {application_xmlns_xsi, application_xmlns_xsd, application_xsi_schemaLocation, application_xmlns};  
  public static final String[] docAttributes = {doc_title, doc_xml_lang};
  public static final String[] includeAttributes = {include_href};
  public static final String[] resourcesAttributes = {resources_base};
  public static final String[] resourceAttributes = {resource_id, resource_path, resource_type, resource_queryType};
  public static final String[] resource_typeAttributes = {resource_type_id};
  public static final String[] methodAttributes = {method_href, method_id, method_name};
  public static final String[] representationAttributes = {representation_element, representation_href, representation_id, representation_mediaType, representation_profile, representation_status};
  public static final String[] faultAttributes = {fault_element, fault_href, fault_id, fault_mediaType, fault_profile, fault_status};
  public static final String[] paramAttributes = {param_id, param_href, param_name, param_style, param_type, param_default, param_path, param_required, param_repeating, param_fixed};
  public static final String[] optionAttributes = {option_value};
  public static final String[] linkAttributes = {link_rel, link_resource_type, link_rev};
  
  // default wadl namespace and schema stuff
  public static final String xmlns_xsi = "http://www.w3.org/2001/XMLSchema-instance";
  public static final String xmlns_xsd = "http://www.w3.org/2001/XMLSchema";  
  public static final String xsi_schemaLocation = "http://research.sun.com/wadl/2006/10 wadl.xsd";
  public static final String xmlns = "http://research.sun.com/wadl/2006/10"; 
  
  public WadlXml(ApplicationNode application) {    
    // <application>        
    createApplicationElement(application);        
  }  
    
  public String dump() {
    if (wadl.hasChildNodes()) {
      String regExp = "><";       
      return (xmlHeader + wadl.toString()).replaceAll(regExp, ">\n<");
    }
    else {
      return "";
    }
  }
  
  private void createDocElements(Vector documentation, Node parentElement) {    
    Iterator iterator = documentation.iterator();
    while (iterator.hasNext()) {
      // <doc xml:lang="" title="xsd:string">bla</doc>
      DocNode doc = (DocNode) iterator.next();
      Element docElement = wadl.createElement(docNode);
      docElement.setAttribute(doc_xml_lang, doc.getXmlLang());
      docElement.setAttribute(doc_title, doc.getTitle());      
      docElement.appendChild(wadl.createTextNode(doc.getText()));
      
      parentElement.appendChild(docElement);
    }    
  }
  
  private void createApplicationElement(ApplicationNode application) {
    // applicationChildren = {resourcesNode, grammarsNode, resourceTypeNode, methodNode, representationNode, faultNode, docNode}
    Element applicationElement = wadl.createElement(applicationNode);
    applicationElement.setAttribute(application_xmlns_xsi, xmlns_xsi);
    applicationElement.setAttribute(application_xmlns_xsd, xmlns_xsd);
    applicationElement.setAttribute(application_xsi_schemaLocation, xsi_schemaLocation);
    applicationElement.setAttribute(application_xmlns, xmlns);    
  
    // external additional namespaces
    Vector allNamespaces = application.getAllNamespaces();
    Iterator namespaceIterator = allNamespaces.iterator();
    int namespaceCounter = 0;
    // add additional application-specific namespaces
    while (namespaceIterator.hasNext()) {
      NamespaceAttribute namespace = (NamespaceAttribute) namespaceIterator.next();
      if (namespace.getName() == null) {
        applicationElement.setAttribute(application_xmlns_extNs + namespaceCounter, namespace.getValue());
      }
      else {
        applicationElement.setAttribute(namespace.getName(), namespace.getValue());
      }
      namespaceCounter++;
    }  
    
    // <grammars>
    if (application.getGrammars() != null) {
      createGrammarsElement(application.getGrammars(), applicationElement);          
    }
    
    // <resources base="xsd:anyURI">
    if (application.getResources() != null) {      
      createResourcesElement(application.getResources(), applicationElement);      
    }
    
    // <resource_type>
    if (application.getAllResourceTypes() != null) {
      Vector allResourceTypes = application.getAllResourceTypes();
      Iterator allResourceTypesIterator = allResourceTypes.iterator();
      while (allResourceTypesIterator.hasNext()) {
        createResourceTypeElement((ResourceTypeNode) allResourceTypesIterator.next(), applicationElement);
      }
    }
    
    // <method>
    if (application.getAllMethods() != null) {
      Vector allMethods = application.getAllMethods();
      Iterator allMethodsIterator = allMethods.iterator();
      while (allMethodsIterator.hasNext()) {
        createMethodElement((MethodNode) allMethodsIterator.next(), applicationElement);
      }
    }
    
    // <representation>
    if (application.getAllRepresentations() != null) {
      Vector allRepresentations = application.getAllRepresentations();
      Iterator allRepresentationsIterator = allRepresentations.iterator();
      while (allRepresentationsIterator.hasNext()) {
        createRepresentationElement((RepresentationNode) allRepresentationsIterator.next(), applicationElement);
      }
    }
    
    // <param>
    if (application.getAllParams() != null) {
      Vector allParams = application.getAllParams();
      Iterator allParamsIterator = allParams.iterator();
      while (allParamsIterator.hasNext()) {
        createParamElement((ParamNode) allParamsIterator.next(), applicationElement);
      }
    }
    
    // <fault>
    if (application.getAllFaults() != null) {
      Vector allFaults = application.getAllFaults();
      Iterator allFaultsIterator = allFaults.iterator();
      while (allFaultsIterator.hasNext()) {
        createFaultElement((FaultNode) allFaultsIterator.next(), applicationElement);
      }
    }
    
    // <doc>
    if (application.getAllDocs() != null) {      
      createDocElements(application.getAllDocs(), applicationElement);      
    }
    
    wadl.appendChild(applicationElement);
  }
  
  /**
   * @param resourceType
   * @param applicationElement
   */
  private void createResourceTypeElement(ResourceTypeNode resourceType, Element applicationElement) {
    //resource_typeChildren = {paramNode, methodNode, docNode};
    Element resourceTypeElement = wadl.createElement(resourceTypeNode);
    
    // <param>
    Vector allResourceParams = resourceType.getAllParams();
    Iterator resourceParamIterator = allResourceParams.iterator();
    while (resourceParamIterator.hasNext()) {                  
      createParamElement((ParamNode) resourceParamIterator.next(), resourceTypeElement);     
    }
    
    // <method>
    Vector allMethods =  resourceType.getAllMethods();
    Iterator methodIterator = allMethods.iterator();
    while (methodIterator.hasNext()) {      
      // <method name="{GET|POST|PUT|DELETE}">      
      createMethodElement((MethodNode) methodIterator.next(), resourceTypeElement);                        
    }
    
    // <doc>
    createDocElements(resourceType.getAllDocs(), resourceTypeElement);
    
    applicationElement.appendChild(resourceTypeElement);
  }

  private void createGrammarsElement(GrammarsNode grammars, Element applicationElement) {
    // grammarsChildren = {includeNode, docNode}    
    Element grammarsElement = wadl.createElement(grammarsNode);
    // <include>    
    if (grammars != null) {
      Vector allIncludes = grammars.getAllIncludes();
      Iterator includeIterator = allIncludes.iterator();
      while (includeIterator.hasNext()) {
        Element includeElement =  wadl.createElement(includeNode);
        includeElement.setAttribute(include_href, (String) includeIterator.next());
        grammarsElement.appendChild(includeElement);
      }      
    }  
    
    // <doc>
    createDocElements(grammars.getAllDocs(), grammarsElement);
    
    applicationElement.appendChild(grammarsElement);    
  }

  private void createResourcesElement(ResourcesNode resources, Element applicationElement) {
    // resourcesChildren = {resourceNode, docNode}
    Element resourcesElement = wadl.createElement(resourcesNode);    
    resourcesElement.setAttribute(resources_base, resources.getBase());
    
    // <resource path="xsd:string">
    Vector allResources =  resources.getAllResources();
    Iterator resourceIterator = allResources.iterator(); 
    while (resourceIterator.hasNext()) {      
      createResourceElement((ResourceNode) resourceIterator.next(), resourcesElement);                  
    }
    
    // <doc>
    createDocElements(resources.getAllDocs(), resourcesElement);
    
    applicationElement.appendChild(resourcesElement);
  }
    
  private void createResourceElement(ResourceNode resource, Element parentElement) {
    // resourceChildren = {paramNode, methodNode, resourceNode, docNode}
    Element resourceElement = wadl.createElement(resourceNode);
    if (resource.getHref() != null) {
      resourceElement.setAttribute(resource_href, resource.getHref());
    }
    else {    
      resourceElement.setAttribute(resource_path, resource.getPath());
      if (resource.getId() != null) resourceElement.setAttribute(resource_id, resource.getId());
    }
    
    // <resource>
    Vector allInnerResources =  resource.getAllResources();
    Iterator innerResourceIterator = allInnerResources.iterator(); 
    while (innerResourceIterator.hasNext()) {                     
      createResourceElement((ResourceNode) innerResourceIterator.next(), resourceElement);      
    }
    
    // <doc>
    createDocElements(resource.getAllDocs(), resourceElement);              
    
    // <param>
    Vector allResourceParams = resource.getAllParams();
    Iterator resourceParamIterator = allResourceParams.iterator();
    while (resourceParamIterator.hasNext()) {                  
      createParamElement((ParamNode) resourceParamIterator.next(), resourceElement);     
    }
    
    // <method>
    Vector allMethods =  resource.getAllMethods();
    Iterator methodIterator = allMethods.iterator();
    while (methodIterator.hasNext()) {      
      // <method name="{GET|POST|PUT|DELETE}">      
      createMethodElement((MethodNode) methodIterator.next(), resourceElement);                        
    }    
    
    parentElement.appendChild(resourceElement);
  }
  
  private void createMethodElement(MethodNode method, Element parentElement) {
    // methodChildren = {requestNode, responseNode, docNode};
    Element methodElement = wadl.createElement(methodNode);
    if (method.getHref() != null) {
      methodElement.setAttribute(method_href, method.getHref());
    }
    else {
      methodElement.setAttribute(method_name, method.getName());
      if (method.getId() != null) methodElement.setAttribute(method_id, method.getId());
    }
        
    // <request>      
    createRequestElement(method.getRequest(), methodElement);            
    
    // <response>
    createResponseElement(method.getResponse(), methodElement);
    
    // <doc>
    createDocElements(method.getAllDocs(), methodElement);
    
    parentElement.appendChild(methodElement);
  }
  
  private void createRequestElement(RequestNode request, Element parentElement) {
    if (request == null) {
      return;
    }
    // requestChildren = {representationNode, paramNode, docNode}
    Element requestElement = wadl.createElement(requestNode);
    
    // <param>
    Vector allParams = request.getAllParams();
    Iterator paramIterator = allParams.iterator();
    while (paramIterator.hasNext()) {        
      // <param id=""? name=""1 style="{query|header}"1 type="xsd:string"? default=""? required=""? repeating=""? fixed="xsd:string"? />              
      createParamElement((ParamNode) paramIterator.next(), requestElement);      
    }
    
    // <representation>
    Vector allRepresentations = request.getAllRepresentations();
    Iterator allRepresentationsIterator = allRepresentations.iterator();
    while (allRepresentationsIterator.hasNext()) {
      // <representation mediaType=""? element=""? profile=""? status=""? />*      
      createRepresentationElement((RepresentationNode) allRepresentationsIterator.next(), requestElement);     
    }
    
    // <doc>
    createDocElements(request.getAllDocs(), requestElement);

    parentElement.appendChild(requestElement);
  }
  
  private void createParamElement(ParamNode param, Element parentElement) {
    // paramChildren = {optionNode, linkNode, docNode}
    Element paramElement = wadl.createElement(paramNode);
    if (param.getHref() != null) {
      paramElement.setAttribute(param_href, param.getHref());
    }
    else {
      if (!param.getName().equals("")) paramElement.setAttribute(param_name, param.getName());          
      if (!param.getType().equals("")) paramElement.setAttribute(param_type, param.getType());
      if (!param.getStyle().equals("")) paramElement.setAttribute(param_style, param.getStyle());
      if (!param.getDefaultValue().equals("")) paramElement.setAttribute(param_default, param.getDefaultValue());
      if (!param.getFixedValue().equals("")) paramElement.setAttribute(param_fixed, param.getFixedValue());
      if (!param.getPath().equals("")) paramElement.setAttribute(param_path, param.getPath());
      if (param.getIsRequired()) paramElement.setAttribute(param_required, "" + param.getIsRequired());
      if (param.getIsRepeating()) paramElement.setAttribute(param_repeating, "" + param.getIsRepeating());
      if (param.getId() != null) paramElement.setAttribute(param_id, param.getId());
    }    
    
    // <option>
    if (param.getOptions().size() > 0) {
      Iterator optionsIterator = param.getOptions().iterator();
      while (optionsIterator.hasNext()) {
        Element optionElement = wadl.createElement(optionNode);
        optionElement.setAttribute(option_value, (String) optionsIterator.next());
        paramElement.appendChild(optionElement);
      }
    }
    
    // <link>
    if (param.getAllLinks() != null) {
      
    }   
    
    // <doc>
    Vector paramDoc = param.getAllDocs();
    Iterator paramDocIterator = paramDoc.iterator();
    while (paramDocIterator.hasNext()) {
      DocNode docNode = (DocNode) paramDocIterator.next();
      if (docNode.getText().equals("")) {
        docNode.setText("Estimated Type ("  + param.getEstimateQuality() + "): [" + param.getType() + "]");
      }
    }
    createDocElements(paramDoc, paramElement);
    
    parentElement.appendChild(paramElement);
  }
  
  private void createResponseElement(ResponseNode response, Element parentElement) {
    if (response == null) {
      return;
    }
    // responseChildren = {representationNode, faultNode, paramNode, docNode}
    Element responseElement = wadl.createElement(responseNode);
    
    // <representation>
    Vector allRepresentations = response.getAllRepresentations();
    Iterator allRepresentationsIterator = allRepresentations.iterator();
    while (allRepresentationsIterator.hasNext()) {
      // <representation mediaType=""? element=""? profile=""? status=""? />*      
      createRepresentationElement((RepresentationNode) allRepresentationsIterator.next(), responseElement);      
    }

    // <fault>
    Vector allFaults = response.getAllFaults();
    Iterator allFaultsIterator = allFaults.iterator();
    while (allFaultsIterator.hasNext()) {
      // <fault mediaType=""? element=""? profile=""? status=""? />*      
      createFaultElement((FaultNode) allFaultsIterator.next(), responseElement);      
    }
    
    // <param>
    Vector allParams = response.getAllParams();
    Iterator paramIterator = allParams.iterator();
    while (paramIterator.hasNext()) {        
      // <param id=""? name=""1 style="{query|header}"1 type="xsd:string"? default=""? required=""? repeating=""? fixed="xsd:string"? />              
      createParamElement((ParamNode) paramIterator.next(), responseElement);
    }
    
    // <doc>
    createDocElements(response.getAllDocs(), responseElement);
    
    parentElement.appendChild(responseElement);
  }
  
  private void createRepresentationElement(RepresentationNode representation, Element parentElement) {
    // representationChildren = {paramNode, docNode}
    Element representationElement = wadl.createElement(representationNode);
    if (representation.getHref() != null) {
      representationElement.setAttribute(representation_href, representation.getHref());
    }
    else {
      if (!representation.getMediaType().equals("")) representationElement.setAttribute(representation_mediaType, representation.getMediaType());
      if (!representation.getElement().equals("")) representationElement.setAttribute(representation_element, representation.getElement());
      if (!representation.getStatus().equals("")) representationElement.setAttribute(representation_status, representation.getStatus());
      if (!representation.getProfile().equals("")) representationElement.setAttribute(representation_profile, representation.getProfile());
      if (representation.getId() != null) representationElement.setAttribute(representation_id, representation.getId());
    }    
    
    // <param>
    Vector allRepresentationParams = representation.getAllParams();
    Iterator representationParamIterator = allRepresentationParams.iterator();
    while (representationParamIterator.hasNext()) {        
      // <param id=""? name=""1 style="{query|header}"1 type="xsd:string"? default=""? required=""? repeating=""? fixed="xsd:string"? />            
      createParamElement((ParamNode) representationParamIterator.next(), representationElement);      
    }
    
    // <doc>
    createDocElements(representation.getAllDocs(), representationElement);
    
    parentElement.appendChild(representationElement);
  }
  
  private void createFaultElement(FaultNode fault, Element parentElement) {
    // faultChildren = {paramNode, docNode}
    Element faultElement = wadl.createElement(faultNode);
    
    // <fault>
    if (fault.getHref() != null) {
      faultElement.setAttribute(fault_href, fault.getHref());
    }
    else {      
      if (!fault.getMediaType().equals("")) faultElement.setAttribute(fault_mediaType, fault.getMediaType());
      if (!fault.getElement().equals("")) faultElement.setAttribute(fault_element, fault.getElement());
      if (!fault.getStatus().equals("")) faultElement.setAttribute(fault_status, fault.getStatus());
      if (!fault.getProfile().equals("")) faultElement.setAttribute(fault_profile, fault.getProfile());
      if (fault.getId() != null) faultElement.setAttribute(fault_id, fault.getId());
    }    
    
    // <doc>
    createDocElements(fault.getAllDocs(), faultElement);
    
    parentElement.appendChild(faultElement);
  }
}

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import com.google.code.apis.rest.client.GUI.CustomTypesDialog;
import com.google.code.apis.rest.client.GUI.GuiFactory;
import com.google.code.apis.rest.client.GUI.ParameterTree;
import com.google.code.apis.rest.client.GUI.SettingsDialog;
import com.google.code.apis.rest.client.Util.SyntaxHighlighter;
import com.google.code.apis.rest.client.Util.TypeEstimator;
import com.google.code.apis.rest.client.Util.Uri;
import com.google.code.apis.rest.client.Wadl.Analyzer;
import com.google.code.apis.rest.client.Wadl.ApplicationNode;
import com.google.code.apis.rest.client.Wadl.FaultNode;
import com.google.code.apis.rest.client.Wadl.GenericNode;
import com.google.code.apis.rest.client.Wadl.ParamNode;
import com.google.code.apis.rest.client.Wadl.RepresentationNode;
import com.google.code.apis.rest.client.Wadl.RequestNode;
import com.google.code.apis.rest.client.Wadl.ResourceNode;
import com.google.code.apis.rest.client.Wadl.ResourceTypeNode;
import com.google.code.apis.rest.client.Wadl.ResponseNode;
import com.google.code.apis.rest.client.Wadl.WadlXml;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

      parentNode = parent;
      parentTreeItem = parentItem;
      paramCounter = reqParamCounter;
      requestString = reqString;
  
      parameterPanelContainer.add(new HTML(SyntaxHighlighter.highlight("<" + WadlXml.paramNode + " ")));
      
      HorizontalPanel parameterPanel = new HorizontalPanel();
      
      VerticalPanel parameterPanelLeft = new VerticalPanel();
      parameterPanelLeft.setWidth("1em");
      parameterPanelLeft.add(new HTML("&nbsp;"));
      parameterPanel.add(parameterPanelLeft);
      
      VerticalPanel parameterPanelRight = new VerticalPanel();
      
      if (param.getId() != null) {
        HorizontalPanel parameterPanel0 = new HorizontalPanel();    
        parameterPanel0.add(new HTML(SyntaxHighlighter.highlight(WadlXml.param_id + "=\"")));
        String id = param.getId();
        final TextBox parameterId = new TextBox();
        parameterId.setText(id);
        parameterId.addChangeListener(new ChangeListener() {
          public void onChange(Widget sender) {
            param.updateId(param.getId(), parameterId.getText());         
          }
        });         
        parameterPanel0.add(parameterId);
        parameterPanel0.add(new HTML(SyntaxHighlighter.highlight("\"")));   
        parameterPanelRight.add(parameterPanel0);
      }
      
      HorizontalPanel parameterPanel1 = new HorizontalPanel();    
      parameterPanel1.add(new HTML(SyntaxHighlighter.highlight(WadlXml.param_name + "=\"")));
      String name = param.getName();
      final TextBox parameterName = new TextBox();
      parameterName.setText(name);
      parameterName.addChangeListener(new ChangeListener() {
        public void onChange(Widget sender) {
          requestString = param.getApplication().getAnalyzer().getRequestString();
          updateParamName(parameterName.getText());
          param.getApplication().getAnalyzer().setRequestString(requestString);
        }
      });    
      parameterName.addKeyboardListener(new KeyboardListener() {
        public void onKeyDown(Widget sender, char keyCode, int modifiers) {               
        }
  
        public void onKeyPress(Widget sender, char keyCode, int modifiers) {               
        }
  
        public void onKeyUp(Widget sender, char keyCode, int modifiers) {
          requestString = param.getApplication().getAnalyzer().getRequestString();
          updateParamName(parameterName.getText());
          param.getApplication().getAnalyzer().setRequestString(requestString);
        }      
      });    
      parameterPanel1.add(parameterName);
      parameterPanel1.add(new HTML(SyntaxHighlighter.highlight("\"")));   
      parameterPanelRight.add(parameterPanel1);
  
      HorizontalPanel parameterPanel2 = new HorizontalPanel();
      parameterPanel2.add(new HTML(SyntaxHighlighter.highlight(WadlXml.param_type + "=\"")));
      final ListBox parameterType = new ListBox();
      parameterType.setVisibleItemCount(1);
      addTypes(parameterType);        
      String supposedType = param.getType();   
      parameterType.setSelectedIndex(indexOfValue(supposedType));    
      parameterPanel2.add(parameterType);    
      parameterPanel2.add(new HTML(SyntaxHighlighter.highlight("\"")));    
     
      if (param.getEstimateQuality().equals(TypeEstimator.sure)) {
        estimationQualityHtml = sureHtml; 
      }
      else if (param.getEstimateQuality().equals(TypeEstimator.supposed)) {
        estimationQualityHtml = believedHtml;
      }
      else if (param.getEstimateQuality().equals(TypeEstimator.unsure)) {
        estimationQualityHtml = unsureHtml;
      }
      else if (param.getEstimateQuality().equals(TypeEstimator.manual)) {
        estimationQualityHtml = manualHtml;
      }
      else {
        estimationQualityHtml = new HTML();
      }
      parameterPanel2.add(estimationQualityHtml);
      parameterType.addChangeListener(new ChangeListener() {
        public void onChange(Widget sender) {
          String selectedType = parameterType.getItemText(parameterType.getSelectedIndex());
          if (selectedType.equals(GuiFactory.strings.newCustomType())) {
            CustomTypesDialog.show(parameterType, param, (GenericNode) parentNode, parentTreeItem, paramCounter, estimationQualityHtml);                   
          }
          else {
            updateParam(selectedType);
          }
        }    
      });
  
      parameterPanelRight.add(parameterPanel2);
      
      HorizontalPanel parameterPanel4 = new HorizontalPanel();
      parameterPanel4.add(new HTML(SyntaxHighlighter.highlight(WadlXml.param_style + "=\"")));
      final ListBox parameterStyle = new ListBox();
      parameterStyle.setVisibleItemCount(1);      
      if (parentNode instanceof ResourceTypeNode) {       
        addResourceTypeStyles(parameterStyle);
      }
      else if (parentNode instanceof ResourceNode) {       
        addResourceStyles(parameterStyle);
      }
      else if (parentNode instanceof RequestNode) {       
        addRequestStyles(parameterStyle);
      }
      else if (parentNode instanceof ResponseNode) {       
        addResponseStyles(parameterStyle);
      }
      else if (parentNode instanceof RepresentationNode) {       
        addRepresentationStyles(parameterStyle);
      }

      else if (parentNode instanceof FaultNode) {       
