/** Performs the update. */
  private boolean doUpdate() {
    try {
      setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

      Map<String, Object> properties = new HashMap<String, Object>();
      for (PropertyInputPanel propertyPanel : propertyPanels) {
        if (propertyPanel.includeInUpdate()) {
          properties.put(propertyPanel.getId(), propertyPanel.getValue());
        }
      }

      if (properties.isEmpty()) {
        return false;
      }

      ObjectId newId = object.updateProperties(properties, false);

      if ((newId != null) && newId.getId().equals(model.getCurrentObject().getId())) {
        try {
          model.reloadObject();
          model.reloadFolder();
        } catch (Exception ex) {
          ClientHelper.showError(null, ex);
        }
      }

      return true;
    } catch (Exception ex) {
      ClientHelper.showError(this, ex);
      return false;
    } finally {
      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }
  }
  public void testChangeCompression() throws NimbitsException {
    Point p = PointModelFactory.createPointModel(null);

    EntityName name =
        (CommonFactoryLocator.getInstance()
            .createName("test" + UUID.randomUUID().toString(), EntityType.point));
    p.setFilterValue(0.0);
    ClientHelper.client().addPoint(name, p);

    Point px = ClientHelper.client().getPoint(name);

    Assert.assertNotNull(px);
    px.setFilterValue(2.0);
    ClientHelper.client().updatePoint(px);

    Point px2 = ClientHelper.client().getPoint(name);
    Assert.assertEquals(2.0, px2.getFilterValue());
    Assert.assertEquals(px.getKey(), px2.getKey());
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      fail();
    }
    // double x2 = testCompression(p);
    ClientHelper.client().deletePoint(name);
    // Assert.assertEquals(255.0, x2);

    // gClient.DeletePoint(p.getValue());
  }
  public void testCompressionSeperateAlternatingValuesPostsNoDate() throws Exception {

    Point p = PointModelFactory.createPointModel(null);

    EntityName name =
        (CommonFactoryLocator.getInstance()
            .createName("test" + UUID.randomUUID().toString(), EntityType.point));
    p.setFilterValue(0.1);
    Point result = ClientHelper.client().addPoint(name);
    assertNotNull(result);

    double rx = 0.0;

    try {

      for (int i = 0; i < 40; i++) {
        StringBuilder b = new StringBuilder();
        if (rx == 0.0) {
          rx = 1.0;
        } else {
          rx = 0.0;
        }

        b.append("&p2=")
            .append(URLEncoder.encode(name.getValue(), Const.CONST_ENCODING))
            .append("&v2=")
            .append(rx);
        // System.out.println( b.toString());
        System.out.println(ClientHelper.client().recordBatch(b.toString()));
        Thread.sleep(100);
      }
      Thread.sleep(3000);
      List<Value> v = ClientHelper.client().getSeries(name, 40);
      double retVal = 0.0;
      for (Value x : v) {
        retVal += x.getDoubleValue();
      }

      DecimalFormat twoDForm = new DecimalFormat("#.##");
      retVal = Double.valueOf(twoDForm.format(retVal));
      ClientHelper.client().deletePoint(name);
      Assert.assertEquals(20.0, retVal);

    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  @Test
  public void testCompression() throws NimbitsException {
    Point p = PointModelFactory.createPointModel(null);

    EntityName name =
        (CommonFactoryLocator.getInstance().createName("test" + UUID.randomUUID().toString()));
    p.setFilterValue(2.0);
    Point result = ClientHelper.client().addPoint(name, p);
    assertNotNull(result);
    Point test = ClientHelper.client().getPoint(name);
    assertNotNull(test);
    double x = testCompression(name);

    // Assert.assertEquals(255.0, x);
    // ClientHelper.client().deletePoint(p.getName());
  }
  public void testNoCompression() throws Exception {
    final Point p = PointModelFactory.createPointModel(null);
    final EntityName name =
        CommonFactoryLocator.getInstance()
            .createName("test" + UUID.randomUUID().toString(), EntityType.point);
    p.setExpire(1);
    p.setFilterValue(0);
    final Point point = ClientHelper.client().addPoint(name, p);
    assertNotNull(point);

    final double x = testCompression(name);
    ClientHelper.client().deletePoint(name);

    Assert.assertEquals(345.0, x);

    //   gClient.DeletePoint(p.getValue());
  }
  public void testCompressionSeparatePostsNoDate() throws Exception {
    Point p = PointModelFactory.createPointModel(null);
    EntityName name =
        (CommonFactoryLocator.getInstance()
            .createName("test" + UUID.randomUUID().toString(), EntityType.point));
    p.setFilterValue(0.1);
    ClientHelper.client().addPoint(name);

    double rx = 0.0;

    try {

      for (int i = 0; i < 40; i++) {
        StringBuilder b = new StringBuilder();
        rx += 0.1;

        b.append("&p1=")
            .append(URLEncoder.encode(name.getValue(), Const.CONST_ENCODING))
            .append("&v1=")
            .append(rx);
        // System.out.println( b.toString());
        ClientHelper.client().recordBatch(b.toString());
        System.out.println(rx);
        Thread.sleep(1000);
      }

      Thread.sleep(2000);
      List<Value> v = ClientHelper.client().getSeries(name.getValue(), 10);
      double retVal = 0.0;
      for (Value x : v) {
        retVal += x.getDoubleValue();
        System.out.println(x.getDoubleValue());
      }

      DecimalFormat twoDForm = new DecimalFormat("#.##");
      retVal = Double.valueOf(twoDForm.format(retVal));
      ClientHelper.client().deletePoint(name.getValue());

      assertEquals(30.0, retVal, 0.0);

    } catch (IOException e) {

    } catch (InterruptedException e) {

    }
  }
 @Override
 public String getCiSvnPath() throws PhrescoException {
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(configuration.getServerPath() + FrameworkConstants.REST_CI_SVN_PATH);
   return resource.accept(MediaType.TEXT_PLAIN).get(String.class);
 }
  private List<FileEntry> readScriptLibrary() {

    URI propFile = null;

    String externalScripts = System.getProperty(SYSPROP_SCRIPTS);
    if (externalScripts == null) {
      propFile = ClientHelper.getClasspathURI(GROOVY_SCRIPT_FOLDER + GROOVY_SCRIPT_LIBRARY);
    } else {
      propFile = (new File(externalScripts)).toURI();
    }

    List<FileEntry> result = ClientHelper.readFileProperties(propFile);

    if (result == null || result.isEmpty()) {
      result = Collections.singletonList(new FileEntry("Groovy Console", null));
    }

    return result;
  }
 private List<ApplicationType> getApplicationTypesFromServer() throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.getApplicationTypesFromServer()");
   }
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   Client client = ClientHelper.createClient();
   WebResource resource = client.resource(configuration.getServerPath() + REST_APPS_PATH);
   Builder builder = resource.accept(MediaType.APPLICATION_JSON_TYPE);
   GenericType<List<ApplicationType>> genericType = new GenericType<List<ApplicationType>>() {};
   return builder.get(genericType);
 }
  public List<Environment> getEnvInfoFromService() throws PhrescoException {
    if (debugEnabled) {
      S_LOGGER.debug("Entering Method ServiceManagerImpl.getEnvFromService()");
    }
    Client client = ClientHelper.createClient();
    FrameworkConfiguration frameworkConfig = PhrescoFrameworkFactory.getFrameworkConfig();
    WebResource resource = client.resource(frameworkConfig.getServerPath() + REST_ENVE_PATH);
    Builder builder = resource.accept(MediaType.APPLICATION_JSON_TYPE);

    GenericType<List<Environment>> genericType = new GenericType<List<Environment>>() {};
    return builder.get(genericType);
  }
 @Override
 public List<Reports> getReports(String techId) throws PhrescoException {
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(
           configuration.getServerPath() + FrameworkConstants.REST_REPORTS + "/" + techId);
   Builder builder = resource.accept(MediaType.APPLICATION_JSON);
   GenericType<List<Reports>> genericType = new GenericType<List<Reports>>() {};
   List<Reports> reportList = builder.get(genericType);
   return reportList;
 }
 @Override
 public SearchContext startSearch(
     SrvSession sess, TreeConnection tree, String searchPath, int attrib)
     throws FileNotFoundException {
   FileFilterMode.setClient(ClientHelper.getClient(sess));
   try {
     SearchContext context = diskInterface.startSearch(sess, tree, searchPath, attrib);
     return context;
   } finally {
     FileFilterMode.clearClient();
   }
 }
  private static double testCompression(final EntityName name) throws NimbitsException {

    double retVal = 0.0;
    Value vx;
    try {
      for (int i = 0; i < 40; i++) {
        Thread.sleep(10);
        vx = ClientHelper.client().recordValue(name, i, new Date());
        assertNotNull(vx);
      }
      // Thread.sleep(2000);
      final List<Value> v = ClientHelper.client().getSeries(name, 10);
      for (final Value x : v) {
        retVal += x.getDoubleValue();
      }
    } catch (InterruptedException e) {

    }
    System.out.println("End compression integration test " + retVal);

    return retVal;
  }
  public ClientResponse getEmailExtPlugin() throws PhrescoException {
    if (debugEnabled) {
      S_LOGGER.debug("Entering Method ServiceManagerImpl.getEmailExtPlugin");
    }

    Client client = ClientHelper.createClient();
    FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
    WebResource resource =
        client.resource(configuration.getServerPath() + FrameworkConstants.REST_CI_MAIL_PLUGIN);
    resource.accept(MediaType.APPLICATION_OCTET_STREAM);
    ClientResponse response = resource.get(ClientResponse.class);
    return response;
  }
 @Override
 public ClientResponse sendReport(LogInfo loginfo) throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.sendReport(LogInfo loginfo)");
   }
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(configuration.getServerPath() + FrameworkConstants.REST_LOG_PATH);
   ClientResponse response =
       resource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class, loginfo);
   return response;
 }
  private void showLoginForm() {
    loginDialog.showDialog();
    if (!loginDialog.isCanceled()) {
      ClientSession clientSession = loginDialog.getClientSession();

      model.setClientSession(clientSession);

      try {
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        model.loadFolder(clientSession.getStartFolderId(), false);
        model.loadObject(clientSession.getStartFolderId());

        toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(true);
        toolbarButton[BUTTON_TYPES].setEnabled(true);
        toolbarButton[BUTTON_QUERY].setEnabled(model.supportsQuery());
        toolbarButton[BUTTON_CHANGELOG].setEnabled(model.supportsChangeLog());
        toolbarButton[BUTTON_CONSOLE].setEnabled(true);
        toolbarButton[BUTTON_TCK].setEnabled(true);
        toolbarButton[BUTTON_CREATE].setEnabled(true);

        itemMenuItem.setEnabled(model.supportsItems());
        relationshipMenuItem.setEnabled(model.supportsRelationships());
        policyMenuItem.setEnabled(model.supportsPolicies());

        String user = clientSession.getSessionParameters().get(SessionParameter.USER);
        if (user != null) {
          user = "******" + user + ")";
        } else {
          user = "";
        }

        setTitle(
            WINDOW_TITLE + user + " - " + clientSession.getSession().getRepositoryInfo().getName());
      } catch (Exception ex) {
        toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(false);
        toolbarButton[BUTTON_TYPES].setEnabled(false);
        toolbarButton[BUTTON_QUERY].setEnabled(false);
        toolbarButton[BUTTON_CHANGELOG].setEnabled(false);
        toolbarButton[BUTTON_CONSOLE].setEnabled(false);
        toolbarButton[BUTTON_TCK].setEnabled(false);
        toolbarButton[BUTTON_CREATE].setEnabled(false);

        ClientHelper.showError(null, ex);

        setTitle(WINDOW_TITLE);
      } finally {
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      }
    }
  }
 @Override
 public FileInfo getFileInformation(SrvSession sess, TreeConnection tree, String path)
     throws IOException {
   if (logger.isDebugEnabled()) {
     logger.debug("getFileInformation:" + path);
   }
   FileFilterMode.setClient(ClientHelper.getClient(sess));
   try {
     FileInfo info = diskInterface.getFileInformation(sess, tree, path);
     return info;
   } finally {
     FileFilterMode.clearClient();
   }
 }
  public InputStream getMailerXml() throws PhrescoException {
    if (debugEnabled) {
      S_LOGGER.debug("Entering Method ServiceManagerImpl.getMailerXml");
    }

    Client client = ClientHelper.createClient();
    FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
    WebResource resource =
        client.resource(configuration.getServerPath() + FrameworkConstants.REST_CI_MAILER_HOME);
    resource.accept(MediaType.APPLICATION_XML);
    ClientResponse response = resource.type(MediaType.APPLICATION_XML).get(ClientResponse.class);
    InputStream is = response.getEntityInputStream();
    return is;
  }
 @Override
 public void createDirectory(SrvSession sess, TreeConnection tree, FileOpenParams params)
     throws IOException {
   try {
     FileFilterMode.setClient(ClientHelper.getClient(sess));
     try {
       diskInterface.createDirectory(sess, tree, params);
     } finally {
       FileFilterMode.clearClient();
     }
   } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
     throw new AccessDeniedException("Unable to create directory " + params.getPath(), ade);
   }
 }
 public User doLogin(Credentials credentials) throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.doLogin(Credentials credentials)");
   }
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(configuration.getServerPath() + FrameworkConstants.REST_LOGIN_PATH);
   resource.accept(MediaType.APPLICATION_JSON_TYPE);
   ClientResponse response =
       resource.type(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, credentials);
   GenericType<User> genericType = new GenericType<User>() {};
   User userInfo = response.getEntity(genericType);
   return userInfo;
 }
 @Override
 public List<AdminConfigInfo> getAdminConfig() throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.getAdminConfig()");
   }
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(configuration.getServerPath() + FrameworkConstants.REST_ADMIN_CONFIG_PATH);
   resource.accept(MediaType.APPLICATION_JSON_TYPE);
   ClientResponse clientResponse =
       resource.type(MediaType.APPLICATION_JSON_TYPE).get(ClientResponse.class);
   GenericType<List<AdminConfigInfo>> genericType = new GenericType<List<AdminConfigInfo>>() {};
   return clientResponse.getEntity(genericType);
 }
 public List<DownloadInfo> getDownloadsFromService(DownloadPropertyInfo downloadPropertyInfo)
     throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.loadVideosFromService()");
   }
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   Client client = ClientHelper.createClient();
   WebResource resource = client.resource(configuration.getServerPath() + REST_DOWNLOADS_PATH);
   ClientResponse response =
       resource
           .type(MediaType.APPLICATION_JSON_TYPE)
           .post(ClientResponse.class, downloadPropertyInfo);
   GenericType<List<DownloadInfo>> genericType = new GenericType<List<DownloadInfo>>() {};
   List<DownloadInfo> downloadInfo = response.getEntity(genericType);
   return downloadInfo;
 }
 public ClientResponse updateDocumentProject(ProjectInfo info) throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.updateProject(ProjectInfo info)");
   }
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(
           configuration.getServerPath() + FrameworkConstants.REST_APPS_UPDATEDOC_PATH);
   resource.accept(MediaType.APPLICATION_OCTET_STREAM);
   if (debugEnabled) {
     S_LOGGER.debug("updateDocumentProject() ProjectName = " + info.getName());
   }
   ClientResponse response =
       resource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class, info);
   return response;
 }
 public ClientResponse createProject(ProjectInfo info, User userInfo) throws PhrescoException {
   if (debugEnabled) {
     S_LOGGER.debug("Entering Method ServiceManagerImpl.createProject(ProjectInfo info)");
   }
   Client client = ClientHelper.createClient();
   FrameworkConfiguration configuration = PhrescoFrameworkFactory.getFrameworkConfig();
   WebResource resource =
       client.resource(configuration.getServerPath() + FrameworkConstants.REST_APPS_PATH);
   resource.accept(MediaType.APPLICATION_OCTET_STREAM);
   if (debugEnabled) {
     S_LOGGER.debug("createProject() ProjectName = " + info.getName());
   }
   ClientResponse response =
       resource
           .header(Constants.AUTH_TOKEN, userInfo.getToken())
           .type(MediaType.APPLICATION_JSON)
           .post(ClientResponse.class, info);
   //        reSetCacheAppTypes();
   return response;
 }
    public Object getValue() {
      Object result = null;

      if (getStatus() == StatusFlag.Update) {
        try {
          if (propDef.getCardinality() == Cardinality.SINGLE) {
            result = ((PropertyValue) valueComponents.get(0)).getPropertyValue();
          } else {
            List<Object> list = new ArrayList<Object>();
            for (JComponent comp : valueComponents) {
              list.add(((PropertyValue) comp).getPropertyValue());
            }
            result = list;
          }
        } catch (Exception ex) {
          ClientHelper.showError(this, ex);
        }
      }

      return result;
    }
  private void createGUI() {
    setTitle(WINDOW_TITLE);

    setIconImages(ClientHelper.getCmisIconImages());

    // Mac OS X goodies
    if (ClientHelper.isMacOSX()) {
      try {
        Class<?> macAppClass = Class.forName("com.apple.eawt.Application");
        Method macAppGetApp = macAppClass.getMethod("getApplication", (Class<?>[]) null);
        Object macApp = macAppGetApp.invoke(null, (Object[]) null);

        ImageIcon icon = ClientHelper.getCmisIconImage();
        if (icon != null) {
          try {
            macAppClass
                .getMethod("setDockIconImage", new Class<?>[] {Image.class})
                .invoke(macApp, new Object[] {icon.getImage()});
          } catch (Exception e) {
            LOG.debug("Could not set dock icon!", e);
          }
        }

        try {
          Class<?> fullscreenClass = Class.forName("com.apple.eawt.FullScreenUtilities");
          fullscreenClass
              .getMethod("setWindowCanFullScreen", new Class<?>[] {Window.class, Boolean.TYPE})
              .invoke(fullscreenClass, this, true);
        } catch (Exception e) {
          LOG.debug("Could not add fullscreen button!", e);
        }
      } catch (Exception e) {
        LOG.debug("Could not get com.apple.eawt.Application object!", e);
      }
    }

    setLayout(new BorderLayout());

    final ClientFrame thisFrame = this;
    loginDialog = new LoginDialog(this);
    logFrame = new LogFrame();
    infoDialog = new InfoDialog(this);

    Container pane = getContentPane();

    toolBar = new JToolBar("CMIS Toolbar", JToolBar.HORIZONTAL);

    toolbarButton = new JButton[10];

    toolbarButton[BUTTON_CONNECT] =
        new JButton(
            "Connection",
            new ConnectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_CONNECT].setDisabledIcon(
        new ConnectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_CONNECT].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            showLoginForm();
          }
        });

    toolBar.add(toolbarButton[BUTTON_CONNECT]);

    toolBar.addSeparator();

    toolbarButton[BUTTON_REPOSITORY_INFO] =
        new JButton(
            "Repository Info",
            new RepositoryInfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_REPOSITORY_INFO].setDisabledIcon(
        new RepositoryInfoIcon(
            ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_REPOSITORY_INFO].setEnabled(false);
    toolbarButton[BUTTON_REPOSITORY_INFO].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            new RepositoryInfoFrame(model);
          }
        });

    toolBar.add(toolbarButton[BUTTON_REPOSITORY_INFO]);

    toolbarButton[BUTTON_TYPES] =
        new JButton(
            "Types", new TypesIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_TYPES].setDisabledIcon(
        new TypesIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_TYPES].setEnabled(false);
    toolbarButton[BUTTON_TYPES].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            new TypesFrame(model);
          }
        });

    toolBar.add(toolbarButton[BUTTON_TYPES]);

    toolbarButton[BUTTON_QUERY] =
        new JButton(
            "Query", new QueryIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_QUERY].setDisabledIcon(
        new QueryIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_QUERY].setEnabled(false);
    toolbarButton[BUTTON_QUERY].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            new QueryFrame(model);
          }
        });

    toolBar.add(toolbarButton[BUTTON_QUERY]);

    toolbarButton[BUTTON_CHANGELOG] =
        new JButton(
            "Change Log",
            new ChangeLogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_CHANGELOG].setDisabledIcon(
        new ChangeLogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_CHANGELOG].setEnabled(false);
    toolbarButton[BUTTON_CHANGELOG].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            new ChangeLogFrame(model);
          }
        });

    toolBar.add(toolbarButton[BUTTON_CHANGELOG]);

    toolbarButton[BUTTON_CONSOLE] =
        new JButton(
            "Console",
            new ConsoleIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_CONSOLE].setDisabledIcon(
        new ConsoleIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_CONSOLE].setEnabled(false);
    toolbarButton[BUTTON_CONSOLE].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            toolbarConsolePopup.show(
                toolbarButton[BUTTON_CONSOLE], 0, toolbarButton[BUTTON_CONSOLE].getHeight());
          }
        });

    toolBar.add(toolbarButton[BUTTON_CONSOLE]);

    toolbarConsolePopup = new JPopupMenu();
    for (FileEntry fe : readScriptLibrary()) {
      JMenuItem menuItem = new JMenuItem(fe.getName());
      final URI file = fe.getFile();
      menuItem.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              ClientHelper.openConsole(ClientFrame.this, model, file);
            }
          });
      toolbarConsolePopup.add(menuItem);
    }

    toolbarButton[BUTTON_TCK] =
        new JButton(
            "TCK", new TckIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_TCK].setDisabledIcon(
        new TckIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_TCK].setEnabled(false);
    toolbarButton[BUTTON_TCK].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            new TckDialog(thisFrame, model);
          }
        });

    toolBar.add(toolbarButton[BUTTON_TCK]);

    toolBar.addSeparator();

    toolbarCreatePopup = new JPopupMenu();
    documentMenuItem = new JMenuItem("Document");
    documentMenuItem.setEnabled(true);
    toolbarCreatePopup.add(documentMenuItem);
    documentMenuItem.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent event) {
            new CreateDocumentDialog(thisFrame, model);
          }
        });

    itemMenuItem = new JMenuItem("Item");
    itemMenuItem.setEnabled(false);
    toolbarCreatePopup.add(itemMenuItem);
    itemMenuItem.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent event) {
            new CreateItemDialog(thisFrame, model);
          }
        });

    folderMenuItem = new JMenuItem("Folder");
    folderMenuItem.setEnabled(true);
    toolbarCreatePopup.add(folderMenuItem);
    folderMenuItem.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent event) {
            new CreateFolderDialog(thisFrame, model);
          }
        });

    relationshipMenuItem = new JMenuItem("Relationship");
    relationshipMenuItem.setEnabled(false);
    toolbarCreatePopup.add(relationshipMenuItem);
    relationshipMenuItem.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent event) {
            new CreateRelationshipDialog(thisFrame, model);
          }
        });

    policyMenuItem = new JMenuItem("Policy");
    policyMenuItem.setEnabled(false);
    toolbarCreatePopup.add(policyMenuItem);
    policyMenuItem.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent event) {
            new CreatePolicyDialog(thisFrame, model);
          }
        });

    toolbarButton[BUTTON_CREATE] =
        new JButton(
            "Create Object",
            new CreateObjectIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_CREATE].setDisabledIcon(
        new CreateObjectIcon(
            ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_CREATE].setEnabled(false);
    toolbarButton[BUTTON_CREATE].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            toolbarCreatePopup.show(
                toolbarButton[BUTTON_CREATE], 0, toolbarButton[BUTTON_CREATE].getHeight());
          }
        });

    toolBar.add(toolbarButton[BUTTON_CREATE]);

    toolBar.addSeparator();

    toolbarButton[BUTTON_LOG] =
        new JButton(
            "Log", new LogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_LOG].setDisabledIcon(
        new LogIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_LOG].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            logFrame.showFrame();
          }
        });

    toolBar.add(toolbarButton[BUTTON_LOG]);

    toolbarButton[BUTTON_INFO] =
        new JButton(
            "Info", new InfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE));
    toolbarButton[BUTTON_INFO].setDisabledIcon(
        new InfoIcon(ClientHelper.TOOLBAR_ICON_SIZE, ClientHelper.TOOLBAR_ICON_SIZE, false));
    toolbarButton[BUTTON_INFO].addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            infoDialog.showDialog();
          }
        });

    toolBar.add(toolbarButton[BUTTON_INFO]);

    pane.add(toolBar, BorderLayout.PAGE_START);

    folderPanel = new FolderPanel(model);
    detailsTabs = new DetailsTabs(model);

    split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, folderPanel, detailsTabs);

    pane.add(split, BorderLayout.CENTER);

    addWindowListener(this);

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    setPreferredSize(
        new Dimension(
            prefs.getInt(PREFS_WIDTH, (int) (screenSize.getWidth() / 1.5)),
            prefs.getInt(PREFS_HEIGHT, (int) (screenSize.getHeight() / 1.5))));
    setMinimumSize(new Dimension(200, 60));

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();

    split.setDividerLocation(prefs.getInt(PREFS_DIV, getPreferredSize().width / 4));

    if (prefs.getInt(PREFS_X, Integer.MAX_VALUE) == Integer.MAX_VALUE) {
      setLocationRelativeTo(null);
    } else {
      setLocation(prefs.getInt(PREFS_X, 0), prefs.getInt(PREFS_Y, 0));
    }

    setVisible(true);
  }
 @Override
 public BaseIngestTransportClient waitForCluster(ClusterHealthStatus status, TimeValue timeValue)
     throws IOException {
   ClientHelper.waitForCluster(client, status, timeValue);
   return this;
 }
public class LoanProductTestBuilder {
  private static final String LOCALE = "en_GB";
  private static final String DIGITS_AFTER_DECIMAL = "2";
  private static final String INR = "INR";
  private static final String DAYS = "0";
  private static final String WEEK = "1";
  private static final String MONTHS = "2";
  private static final String YEARS = "3";
  private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD = "1";
  private static final String EQUAL_PRINCIPLE_PAYMENTS = "0";
  private static final String EQUAL_INSTALLMENTS = "1";
  private static final String DECLINING_BALANCE = "0";
  private static final String FLAT_BALANCE = "1";
  private static final String MIFOS_STANDARD_STRATEGY = "1";
  // private static final String HEAVENS_FAMILY_STRATEGY ="2";
  // private static final String CREO_CORE_STRATEGY ="3";
  // private static final String RBI_INDIA_STRATEGY ="4";
  private static final String NONE = "1";
  private static final String CASH_BASED = "2";
  private static final String ACCRUAL_BASED = "3";

  private String nameOfLoanProduct = ClientHelper.randomNameGenerator("LOAN_PRODUCT_", 6);
  private String principal = "10000.00";
  private String numberOfRepayments = "0";
  private String repaymentFrequency = WEEK;
  private String repaymentPeriod = "0";
  private String interestRatePerPeriod = "2";
  private String interestRateFrequencyType = MONTHS;
  private String interestType = FLAT_BALANCE;
  private String interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
  private String inArrearsTolerance = "0";
  private final String transactionProcessingStrategy = MIFOS_STANDARD_STRATEGY;
  private String accountingRule = NONE;
  private final String currencyCode = INR;
  private String amortizationType = EQUAL_INSTALLMENTS;
  private String minPrincipal = "1000.00";
  private String maxPrincipal = "100000.00";

  public String build() {
    HashMap<String, String> map = new HashMap<String, String>();

    map.put("name", nameOfLoanProduct);
    map.put("currencyCode", currencyCode);
    map.put("locale", LOCALE);
    map.put("digitsAfterDecimal", DIGITS_AFTER_DECIMAL);
    map.put("principal", principal);
    map.put("numberOfRepayments", numberOfRepayments);
    map.put("repaymentEvery", repaymentPeriod);
    map.put("repaymentFrequencyType", repaymentFrequency);
    map.put("interestRatePerPeriod", interestRatePerPeriod);
    map.put("interestRateFrequencyType", interestRateFrequencyType);
    map.put("amortizationType", amortizationType);
    map.put("interestType", interestType);
    map.put("interestCalculationPeriodType", interestCalculationPeriodType);
    map.put("inArrearsTolerance", inArrearsTolerance);
    map.put("transactionProcessingStrategyId", transactionProcessingStrategy);
    map.put("accountingRule", accountingRule);
    map.put("minPrincipal", minPrincipal);
    map.put("maxPrincipal", maxPrincipal);
    return new Gson().toJson(map);
  }

  public LoanProductTestBuilder withMinPrincipal(final String minPrincipal) {
    this.minPrincipal = minPrincipal;
    return this;
  }

  public LoanProductTestBuilder withMaxPrincipal(final String maxPrincipal) {
    this.maxPrincipal = maxPrincipal;
    return this;
  }

  public LoanProductTestBuilder withLoanName(final String loanName) {
    this.nameOfLoanProduct = loanName;
    return this;
  }

  public LoanProductTestBuilder withPrincipal(final String principal) {
    this.principal = principal;
    return this;
  }

  public LoanProductTestBuilder withNumberOfRepayments(final String numberOfRepayment) {
    this.numberOfRepayments = numberOfRepayment;
    return this;
  }

  public LoanProductTestBuilder withRepaymentTypeAsMonth() {
    this.repaymentFrequency = MONTHS;
    return this;
  }

  public LoanProductTestBuilder withRepaymentTypeAsWeek() {
    this.repaymentFrequency = WEEK;
    return this;
  }

  public LoanProductTestBuilder withRepaymentTypeAsDays() {
    this.repaymentFrequency = DAYS;
    return this;
  }

  public LoanProductTestBuilder withRepaymentAfterEvery(final String repaymentAfterEvery) {
    this.repaymentPeriod = repaymentAfterEvery;
    return this;
  }

  public LoanProductTestBuilder withInterestRateFrequencyTypeAsMonths() {
    this.interestRateFrequencyType = MONTHS;
    return this;
  }

  public LoanProductTestBuilder withInterestRateFrequencyTypeAsYear() {
    this.interestRateFrequencyType = YEARS;
    return this;
  }

  public LoanProductTestBuilder withinterestRatePerPeriod(final String interestRatePerPeriod) {
    this.interestRatePerPeriod = interestRatePerPeriod;
    return this;
  }

  public LoanProductTestBuilder withAmortizationTypeAsEqualPrinciplePayment() {
    this.amortizationType = EQUAL_PRINCIPLE_PAYMENTS;
    return this;
  }

  public LoanProductTestBuilder withAmortizationTypeAsEqualInstallments() {
    this.amortizationType = EQUAL_INSTALLMENTS;
    return this;
  }

  public LoanProductTestBuilder withInterestTypeAsFlat() {
    this.interestType = FLAT_BALANCE;
    return this;
  }

  public LoanProductTestBuilder withInterestTypeAsDecliningBalance() {
    this.interestType = DECLINING_BALANCE;
    return this;
  }

  public LoanProductTestBuilder withInterestCalculationPeriodTypeAsDays() {
    this.interestCalculationPeriodType = DAYS;
    return this;
  }

  public LoanProductTestBuilder withInterestCalculationPeriodTypeAsRepaymentPeriod() {
    this.interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
    return this;
  }

  public LoanProductTestBuilder withInArrearsTolerance(final String amountCanBeWaved) {
    this.inArrearsTolerance = amountCanBeWaved;
    return this;
  }

  public LoanProductTestBuilder withAccountingRuleAsNone() {
    this.accountingRule = NONE;
    return this;
  }

  public LoanProductTestBuilder withAccountingRuleAsCashBased() {
    this.accountingRule = CASH_BASED;
    return this;
  }

  public LoanProductTestBuilder withAccountingRuleAsAccrualBased() {
    this.accountingRule = ACCRUAL_BASED;
    return this;
  }
}
/** Simple property editor. */
public class PropertyEditorFrame extends JFrame {

  private static final long serialVersionUID = 1L;

  private static final String WINDOW_TITLE = "Property Editor";
  private static final ImageIcon ICON_ADD = ClientHelper.getIcon("add.png");

  private final ClientModel model;
  private final CmisObject object;
  private List<PropertyInputPanel> propertyPanels;

  public PropertyEditorFrame(final ClientModel model, final CmisObject object) {
    super();

    this.model = model;
    this.object = object;

    createGUI();
  }

  private void createGUI() {
    setTitle(WINDOW_TITLE);
    setPreferredSize(new Dimension(800, 600));
    setMinimumSize(new Dimension(300, 120));

    setLayout(new BorderLayout());

    final JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

    final Font labelFont = UIManager.getFont("Label.font");
    final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);

    final JPanel topPanel = new JPanel();
    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
    topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    final JLabel nameLabel = new JLabel(object.getName());
    nameLabel.setFont(boldFont);
    topPanel.add(nameLabel);
    topPanel.add(new JLabel(object.getId()));
    add(topPanel, BorderLayout.PAGE_START);

    JScrollPane scrollPane = new JScrollPane(panel);
    add(scrollPane, BorderLayout.CENTER);

    propertyPanels = new ArrayList<PropertyEditorFrame.PropertyInputPanel>();

    int position = 0;
    for (PropertyDefinition<?> propDef : object.getType().getPropertyDefinitions().values()) {
      boolean isUpdatable =
          (propDef.getUpdatability() == Updatability.READWRITE)
              || (propDef.getUpdatability() == Updatability.WHENCHECKEDOUT
                  && object
                      .getAllowableActions()
                      .getAllowableActions()
                      .contains(Action.CAN_CHECK_IN));

      if (isUpdatable) {
        PropertyInputPanel propertyPanel =
            new PropertyInputPanel(propDef, object.getPropertyValue(propDef.getId()), position++);

        propertyPanels.add(propertyPanel);
        panel.add(propertyPanel);
      }
    }

    JButton updateButton = new JButton("Update");
    updateButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    updateButton.setDefaultCapable(true);
    updateButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            if (doUpdate()) {
              dispose();
            }
          }
        });

    add(updateButton, BorderLayout.PAGE_END);

    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
  }

  /** Performs the update. */
  private boolean doUpdate() {
    try {
      setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

      Map<String, Object> properties = new HashMap<String, Object>();
      for (PropertyInputPanel propertyPanel : propertyPanels) {
        if (propertyPanel.includeInUpdate()) {
          properties.put(propertyPanel.getId(), propertyPanel.getValue());
        }
      }

      if (properties.isEmpty()) {
        return false;
      }

      ObjectId newId = object.updateProperties(properties, false);

      if ((newId != null) && newId.getId().equals(model.getCurrentObject().getId())) {
        try {
          model.reloadObject();
          model.reloadFolder();
        } catch (Exception ex) {
          ClientHelper.showError(null, ex);
        }
      }

      return true;
    } catch (Exception ex) {
      ClientHelper.showError(this, ex);
      return false;
    } finally {
      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }
  }

  interface UpdateStatus {
    enum StatusFlag {
      DontChange,
      Update,
      Unset
    }

    void setStatus(StatusFlag status);

    StatusFlag getStatus();
  }

  interface MultivalueManager {
    void addNewValue();

    void removeValue(int pos);

    void moveUp(int pos);

    void moveDown(int pos);
  }

  /** Property input panel. */
  public static class PropertyInputPanel extends JPanel implements UpdateStatus, MultivalueManager {
    private static final long serialVersionUID = 1L;

    private static final Color BACKGROUND1 =
        UIManager.getColor("Table:\"Table.cellRenderer\".background");
    private static final Color BACKGROUND2 = UIManager.getColor("Table.alternateRowColor");
    private static final Color LINE = new Color(0xB8, 0xB8, 0xB8);

    private final PropertyDefinition<?> propDef;
    private final Object value;
    private final Color bgColor;
    private JComboBox changeBox;
    private LinkedList<JComponent> valueComponents;

    public PropertyInputPanel(PropertyDefinition<?> propDef, Object value, int position) {
      super();
      this.propDef = propDef;
      this.value = value;
      bgColor = (position % 2 == 0 ? BACKGROUND1 : BACKGROUND2);
      createGUI();
    }

    private void createGUI() {
      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

      setBackground(bgColor);
      setBorder(
          BorderFactory.createCompoundBorder(
              BorderFactory.createMatteBorder(0, 0, 1, 0, LINE),
              BorderFactory.createEmptyBorder(10, 5, 10, 5)));

      Font labelFont = UIManager.getFont("Label.font");
      Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);

      JPanel titlePanel = new JPanel();
      titlePanel.setLayout(new BorderLayout());
      titlePanel.setBackground(bgColor);
      titlePanel.setToolTipText(
          "<html><b>"
              + propDef.getPropertyType().value()
              + "</b> ("
              + propDef.getCardinality().value()
              + " value)"
              + (propDef.getDescription() != null ? "<br>" + propDef.getDescription() : ""));
      add(titlePanel);

      JPanel namePanel = new JPanel();
      namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.Y_AXIS));
      namePanel.setBackground(bgColor);
      JLabel displayNameLabel = new JLabel(propDef.getDisplayName());
      displayNameLabel.setFont(boldFont);
      namePanel.add(displayNameLabel);
      JLabel idLabel = new JLabel(propDef.getId());
      namePanel.add(idLabel);

      titlePanel.add(namePanel, BorderLayout.LINE_START);

      changeBox = new JComboBox(new Object[] {"Don't change     ", "Update    ", "Unset     "});
      titlePanel.add(changeBox, BorderLayout.LINE_END);

      valueComponents = new LinkedList<JComponent>();
      if (propDef.getCardinality() == Cardinality.SINGLE) {
        JComponent valueField = createInputField(value);
        valueComponents.add(valueField);
        add(valueField);
      } else {
        if (value instanceof List<?>) {
          for (Object v : (List<?>) value) {
            JComponent valueField =
                new MultiValuePropertyInputField(createInputField(v), this, bgColor);
            valueComponents.add(valueField);
            add(valueField);
          }
        }

        JPanel addPanel = new JPanel(new BorderLayout());
        addPanel.setBackground(bgColor);
        JButton addButton = new JButton(ICON_ADD);
        addButton.addActionListener(
            new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                addNewValue();
                setStatus(StatusFlag.Update);
              }
            });
        addPanel.add(addButton, BorderLayout.LINE_END);
        add(addPanel);

        updatePositions();
      }

      setMaximumSize(new Dimension(Short.MAX_VALUE, getPreferredSize().height));
    }

    protected JComponent createInputField(Object value) {
      switch (propDef.getPropertyType()) {
        case INTEGER:
          return new IntegerPropertyInputField(value, this, bgColor);
        case DECIMAL:
          return new DecimalPropertyInputField(value, this, bgColor);
        case DATETIME:
          return new DateTimePropertyInputField(value, this, bgColor);
        case BOOLEAN:
          return new BooleanPropertyInputField(value, this, bgColor);
        default:
          return new StringPropertyInputField(value, this, bgColor);
      }
    }

    private void updatePositions() {
      int n = valueComponents.size();
      for (int i = 0; i < n; i++) {
        MultiValuePropertyInputField comp = (MultiValuePropertyInputField) valueComponents.get(i);
        comp.updatePosition(i, i + 1 == n);
      }
    }

    public void addNewValue() {
      JComponent valueField =
          new MultiValuePropertyInputField(createInputField(null), this, bgColor);
      valueComponents.add(valueField);
      add(valueField, getComponentCount() - 1);

      updatePositions();
      setStatus(StatusFlag.Update);

      revalidate();
    }

    public void removeValue(int pos) {
      remove(valueComponents.remove(pos));

      updatePositions();
      setStatus(StatusFlag.Update);

      revalidate();
    }

    public void moveUp(int pos) {
      JComponent comp = valueComponents.get(pos);
      Collections.swap(valueComponents, pos, pos - 1);

      remove(comp);
      add(comp, pos);

      updatePositions();
      setStatus(StatusFlag.Update);

      revalidate();
    }

    public void moveDown(int pos) {
      JComponent comp = valueComponents.get(pos);
      Collections.swap(valueComponents, pos, pos + 1);

      remove(comp);
      add(comp, pos + 2);

      updatePositions();
      setStatus(StatusFlag.Update);

      revalidate();
    }

    public String getId() {
      return propDef.getId();
    }

    public Object getValue() {
      Object result = null;

      if (getStatus() == StatusFlag.Update) {
        try {
          if (propDef.getCardinality() == Cardinality.SINGLE) {
            result = ((PropertyValue) valueComponents.get(0)).getPropertyValue();
          } else {
            List<Object> list = new ArrayList<Object>();
            for (JComponent comp : valueComponents) {
              list.add(((PropertyValue) comp).getPropertyValue());
            }
            result = list;
          }
        } catch (Exception ex) {
          ClientHelper.showError(this, ex);
        }
      }

      return result;
    }

    public boolean includeInUpdate() {
      return getStatus() != StatusFlag.DontChange;
    }

    public void setStatus(StatusFlag status) {
      switch (status) {
        case Update:
          changeBox.setSelectedIndex(1);
          break;
        case Unset:
          changeBox.setSelectedIndex(2);
          break;
        default:
          changeBox.setSelectedIndex(0);
      }
    }

    public StatusFlag getStatus() {
      switch (changeBox.getSelectedIndex()) {
        case 1:
          return StatusFlag.Update;
        case 2:
          return StatusFlag.Unset;
        default:
          return StatusFlag.DontChange;
      }
    }

    public Dimension getMaximumSize() {
      Dimension size = getPreferredSize();
      size.width = Short.MAX_VALUE;
      return size;
    }
  }

  /** Property value interface. */
  public interface PropertyValue {
    Object getPropertyValue() throws Exception;
  }

  /** String property. */
  public static class StringPropertyInputField extends JTextField implements PropertyValue {
    private static final long serialVersionUID = 1L;

    public StringPropertyInputField(
        final Object value, final UpdateStatus status, final Color bgColor) {
      super(value == null ? "" : value.toString());

      addKeyListener(
          new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {
              status.setStatus(StatusFlag.Update);
            }

            @Override
            public void keyPressed(KeyEvent e) {}
          });
    }

    public Object getPropertyValue() {
      return getText();
    }
  }

  /** Formatted property. */
  public static class AbstractFormattedPropertyInputField extends JFormattedTextField
      implements PropertyValue {
    private static final long serialVersionUID = 1L;

    public AbstractFormattedPropertyInputField(
        final Object value, final Format format, final UpdateStatus status, final Color bgColor) {
      super(format);
      if (value != null) {
        setValue(value);
      }

      addKeyListener(
          new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {
              status.setStatus(StatusFlag.Update);
            }

            @Override
            public void keyPressed(KeyEvent e) {}
          });
    }

    public Object getPropertyValue() throws Exception {
      commitEdit();
      return getValue();
    }
  }

  /** Integer property. */
  public static class IntegerPropertyInputField extends AbstractFormattedPropertyInputField {
    private static final long serialVersionUID = 1L;

    public IntegerPropertyInputField(
        final Object value, final UpdateStatus status, final Color bgColor) {
      super(value, createFormat(), status, bgColor);
      setHorizontalAlignment(JTextField.RIGHT);
    }

    private static DecimalFormat createFormat() {
      DecimalFormat result = new DecimalFormat("#,##0");
      result.setParseBigDecimal(true);
      result.setParseIntegerOnly(true);
      return result;
    }

    public Object getPropertyValue() throws Exception {
      return ((BigDecimal) super.getValue()).toBigIntegerExact();
    }
  }

  /** Decimal property. */
  public static class DecimalPropertyInputField extends AbstractFormattedPropertyInputField {
    private static final long serialVersionUID = 1L;

    public DecimalPropertyInputField(
        final Object value, final UpdateStatus status, final Color bgColor) {
      super(value, createFormat(), status, bgColor);
      setHorizontalAlignment(JTextField.RIGHT);
    }

    private static DecimalFormat createFormat() {
      DecimalFormat result = new DecimalFormat("#,##0.#############################");
      result.setParseBigDecimal(true);
      return result;
    }
  }

  /** Boolean property. */
  public static class BooleanPropertyInputField extends JComboBox implements PropertyValue {
    private static final long serialVersionUID = 1L;

    public BooleanPropertyInputField(
        final Object value, final UpdateStatus status, final Color bgColor) {
      super(new Object[] {true, false});
      setSelectedItem(value == null ? true : value);

      addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              status.setStatus(StatusFlag.Update);
            }
          });
    }

    public Object getPropertyValue() {
      return getSelectedItem();
    }
  }

  /** DateTime property. */
  public static class DateTimePropertyInputField extends JPanel implements PropertyValue {
    private static final long serialVersionUID = 1L;

    private static final String[] MONTH_STRINGS;

    static {
      String[] months = new java.text.DateFormatSymbols().getMonths();
      int lastIndex = months.length - 1;

      if (months[lastIndex] == null || months[lastIndex].length() <= 0) {
        String[] monthStrings = new String[lastIndex];
        System.arraycopy(months, 0, monthStrings, 0, lastIndex);
        MONTH_STRINGS = monthStrings;
      } else {
        MONTH_STRINGS = months;
      }
    }

    private final SpinnerNumberModel day;
    private final SpinnerListModel month;
    private final SpinnerNumberModel year;
    private final SpinnerNumberModel hour;
    private final SpinnerNumberModel min;
    private final SpinnerNumberModel sec;
    private final TimeZone timezone;

    public DateTimePropertyInputField(
        final Object value, final UpdateStatus status, final Color bgColor) {
      setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
      setBackground(bgColor);

      GregorianCalendar cal = (value == null ? new GregorianCalendar() : (GregorianCalendar) value);
      timezone = cal.getTimeZone();

      day = new SpinnerNumberModel(cal.get(Calendar.DATE), 1, 31, 1);
      addSpinner(new JSpinner(day), status);

      month = new SpinnerListModel(MONTH_STRINGS);
      month.setValue(MONTH_STRINGS[cal.get(Calendar.MONTH)]);
      JSpinner monthSpinner = new JSpinner(month);
      JComponent editor = monthSpinner.getEditor();
      if (editor instanceof JSpinner.DefaultEditor) {
        JFormattedTextField tf = ((JSpinner.DefaultEditor) editor).getTextField();
        tf.setColumns(6);
        tf.setHorizontalAlignment(JTextField.RIGHT);
      }
      addSpinner(monthSpinner, status);

      year = new SpinnerNumberModel(cal.get(Calendar.YEAR), 0, 9999, 1);
      JSpinner yearSpinner = new JSpinner(year);
      yearSpinner.setEditor(new JSpinner.NumberEditor(yearSpinner, "#"));
      yearSpinner.getEditor().setBackground(bgColor);
      addSpinner(yearSpinner, status);

      add(new JLabel("  "));

      hour = new SpinnerNumberModel(cal.get(Calendar.HOUR_OF_DAY), 0, 23, 1);
      JSpinner hourSpinner = new JSpinner(hour);
      addSpinner(hourSpinner, status);

      add(new JLabel(":"));

      min = new SpinnerNumberModel(cal.get(Calendar.MINUTE), 0, 59, 1);
      JSpinner minSpinner = new JSpinner(min);
      addSpinner(minSpinner, status);

      add(new JLabel(":"));

      sec = new SpinnerNumberModel(cal.get(Calendar.SECOND), 0, 59, 1);
      JSpinner secSpinner = new JSpinner(sec);
      addSpinner(secSpinner, status);

      add(new JLabel(" " + timezone.getDisplayName(true, TimeZone.SHORT)));
    }

    private void addSpinner(final JSpinner spinner, final UpdateStatus status) {
      spinner.addChangeListener(
          new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
              status.setStatus(StatusFlag.Update);
            }
          });

      add(spinner);
    }

    public Object getPropertyValue() {
      GregorianCalendar result = new GregorianCalendar();

      result.setTimeZone(timezone);

      result.set(Calendar.YEAR, year.getNumber().intValue());
      int mi = 0;
      String ms = month.getValue().toString();
      for (int i = 0; i < MONTH_STRINGS.length; i++) {
        if (MONTH_STRINGS[i].equals(ms)) {
          mi = i;
          break;
        }
      }
      result.set(Calendar.MONTH, mi);
      result.set(Calendar.DATE, day.getNumber().intValue());
      result.set(Calendar.HOUR_OF_DAY, hour.getNumber().intValue());
      result.set(Calendar.MINUTE, min.getNumber().intValue());
      result.set(Calendar.SECOND, sec.getNumber().intValue());

      return result;
    }
  }

  /** Multi value property. */
  public static class MultiValuePropertyInputField extends JPanel implements PropertyValue {
    private static final long serialVersionUID = 1L;

    private static final ImageIcon ICON_UP = ClientHelper.getIcon("up.png");
    private static final ImageIcon ICON_DOWN = ClientHelper.getIcon("down.png");
    private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png");

    private final JComponent component;
    private int position;

    private JButton upButton;
    private JButton downButton;

    public MultiValuePropertyInputField(
        final JComponent component,
        final MultivalueManager mutlivalueManager,
        final Color bgColor) {
      super();
      this.component = component;

      setLayout(new BorderLayout());
      setBackground(bgColor);

      add(component, BorderLayout.CENTER);

      JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
      buttonPanel.setBackground(bgColor);

      upButton = new JButton(ICON_UP);
      upButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.moveUp(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(upButton);

      downButton = new JButton(ICON_DOWN);
      downButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.moveDown(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(downButton);

      JButton removeButton = new JButton(ICON_REMOVE);
      removeButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.removeValue(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(removeButton);

      add(buttonPanel, BorderLayout.LINE_END);
    }

    public void updatePosition(int position, boolean isLast) {
      this.position = position;
      upButton.setEnabled(position > 0);
      downButton.setEnabled(!isLast);
    }

    public Object getPropertyValue() throws Exception {
      return ((PropertyValue) component).getPropertyValue();
    }
  }
}
  /** Multi value property. */
  public static class MultiValuePropertyInputField extends JPanel implements PropertyValue {
    private static final long serialVersionUID = 1L;

    private static final ImageIcon ICON_UP = ClientHelper.getIcon("up.png");
    private static final ImageIcon ICON_DOWN = ClientHelper.getIcon("down.png");
    private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png");

    private final JComponent component;
    private int position;

    private JButton upButton;
    private JButton downButton;

    public MultiValuePropertyInputField(
        final JComponent component,
        final MultivalueManager mutlivalueManager,
        final Color bgColor) {
      super();
      this.component = component;

      setLayout(new BorderLayout());
      setBackground(bgColor);

      add(component, BorderLayout.CENTER);

      JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
      buttonPanel.setBackground(bgColor);

      upButton = new JButton(ICON_UP);
      upButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.moveUp(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(upButton);

      downButton = new JButton(ICON_DOWN);
      downButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.moveDown(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(downButton);

      JButton removeButton = new JButton(ICON_REMOVE);
      removeButton.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              mutlivalueManager.removeValue(MultiValuePropertyInputField.this.position);
            }
          });
      buttonPanel.add(removeButton);

      add(buttonPanel, BorderLayout.LINE_END);
    }

    public void updatePosition(int position, boolean isLast) {
      this.position = position;
      upButton.setEnabled(position > 0);
      downButton.setEnabled(!isLast);
    }

    public Object getPropertyValue() throws Exception {
      return ((PropertyValue) component).getPropertyValue();
    }
  }