private String resultToJSON(Object o) {
		String out = "";

		if (o == null) {
			out = "null"; // legacy with void returning methods in python
		} else if ((o instanceof List) || (o instanceof Vector)) {
			out += "[ ";
			Iterator it = ((List) o).iterator();
			boolean first = true;

			while (it.hasNext()) {
				if (!first) {
					out += ", ";
				} else {
					first = false;
				}
				Object e = it.next();

				out += this.resultToJSON(e);
			}
			out += " ]";
		} else if (o instanceof Enumeration) {
			out += "[ ";
			boolean first = true;

			Enumeration e = (Enumeration) o;

			while (e.hasMoreElements()) {
				if (!first) {
					out += ", ";
				} else {
					first = false;
				}

				out += this.resultToJSON(e);
			}
			out += " ]";
		} else if (o instanceof Hashtable) {
			Hashtable ht = (Hashtable) o;
			Enumeration keys = ht.keys();
			boolean first = true;
			out = "{ ";
			while (keys.hasMoreElements()) {
				if (first) {
					first = false;
				} else {
					out += ", ";
				}

				Object key = keys.nextElement();
				Object value = ht.get(key);

				if (value instanceof String) {
					out += "\"" + key.toString() + "\"" + ": " + "\"" + ht.get(key).toString() + "\"";
				} else {
					out += "\"" + key.toString() + "\": " + this.resultToJSON(value);
				}
			}

			out += " }";
		} else if (o instanceof String) {
			// log.debug("traduco " + o);
			out = "\"" + o.toString() + "\"";
		} else if (o instanceof Integer) {
			out = o.toString();
		} else if (o instanceof Double) {
			out = o.toString();
		} else if (o instanceof ICategory) {
			ICategory category = (ICategory) o;
			out = "{ \"name\": \"" + category.getName() + "\", \"icon\": \"" + category.getIconName() + "\" }";
		} else if (o instanceof ILocation) {
			ILocation location = (ILocation) o;
			// log.debug("traduco " + location.getName());
			out = "{ " + "\"name\": \"" + _(location.getName()) + "\", " + "\"icon\": \"" + location.getIconName() + "\", " + "\"pid\": \"" + location.getPid() + "\"" + "}";
		} else if (o instanceof IAppliance) {
			out += "\"" + ((IAppliance) o).getPid() + "\"";
		} else if (o instanceof IServiceCluster) {
			out += "\"" + ((IServiceCluster) o).getEndPoint().getAppliance().getPid() + "\"";
		} else if (o instanceof IAttributeValue) {
			IAttributeValue v = (IAttributeValue) o;
			Object value = v.getValue();
			if (value instanceof String)
				out += "{ \"type\": \"string\", \"value\": " + "\"" + value.toString() + "\" }";
			else
				out += "{ \"type\": \"double\", \"value\": " + value.toString() + " }";
		} else if (o instanceof byte[]) {
			out += "\"" + byteToHex((byte[]) o) + "\"";
		} else if (o.getClass().isArray()) {
			Object[] o1 = (Object[]) o;

			out += "[ ";
			boolean first = true;

			for (int i = 0; i < o1.length; i++) {
				if (!first) {
					out += ", ";
				} else {
					first = false;
				}
				out += this.resultToJSON(o1[i]);
			}
			out += " ]";
		} else {
			out = "\"" + o.toString() + "\"";
		}
		return out;
	}
 private void renderEndPoints(
     String appRoot, IApplianceConfiguration config, IEndPoint[] endPoints, PrintWriter pw) {
   for (int i = 0; i < endPoints.length; i++) {
     IEndPoint endPoint = endPoints[i];
     IAppliance appliance = endPoint.getAppliance();
     String appliancePid = appliance.getPid();
     Integer endPointId = new Integer(endPoint.getId());
     boolean isAvailable = appliance.isAvailable();
     if (isAvailable) pw.println("<b>");
     else pw.println("<b><font color=\"gray\">");
     String name = null;
     ICategory category = null;
     ILocation location = null;
     if (config != null) {
       name = config.getName(endPointId);
       category = appliancesProxy.getCategory(config.getCategoryPid(endPointId));
       location = appliancesProxy.getLocation(config.getLocationPid(endPointId));
     }
     pw.println("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDPOINT");
     if (!appliance.isSingleton())
       pw.println(
           "&nbsp;(<a href=\""
               + appRoot
               + "/"
               + LABEL
               + "/config/"
               + appliancePid
               + "/"
               + endPointId
               + "\">Configuration</a>)");
     pw.println(
         "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ID: "
             + endPoint.getId()
             + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE: "
             + endPoint.getType()
             + ((name != null) ? "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name: " + name : "")
             + ((category != null)
                 ? "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Category: " + category.getName()
                 : "")
             + ((location != null)
                 ? "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Location: " + location.getName()
                 : ""));
     if (isAvailable)
       pw.println(
           "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
               + (endPointId > 0 ? "Clusters:" : "")
               + "</b><br/>");
     else
       pw.println(
           "<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
               + (endPointId > 0 ? "Clusters:" : "")
               + "</b></font><br/>");
     try {
       IServiceCluster[] clusterArray = endPoint.getServiceClusters(IServiceCluster.SERVER_SIDE);
       if (clusterArray != null && clusterArray.length > 0) {
         renderClusterList(appRoot, appliancePid, endPointId, clusterArray, pw);
       }
       clusterArray = endPoint.getServiceClusters(IServiceCluster.CLIENT_SIDE);
       if (clusterArray != null && clusterArray.length > 0) {
         renderClusterList(appRoot, appliancePid, endPointId, clusterArray, pw);
       }
       String[] clusterNames = endPoint.getAdditionalClusterNames();
       if (clusterNames != null && clusterNames.length > 0) {
         renderClusterList(appRoot, appliancePid, endPoint, clusterNames, pw);
       }
       pw.println("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>");
     } catch (InstanceNotFoundException e) {
       e.printStackTrace();
     } catch (IntrospectionException e) {
       e.printStackTrace();
     } catch (ReflectionException e) {
       e.printStackTrace();
     }
   }
 }
  private void renderApplianceConfiguration(
      String appRoot, IApplianceConfiguration config, Integer endPointId, PrintWriter pw) {
    if (config == null) return;
    String appliancePid = config.getAppliancePid();
    IAppliance appliance = appliancesProxy.getAppliance(appliancePid);
    if (appliance == null) appliance = appliancesProxy.getInstallingAppliance(appliancePid);

    String name = config.getName(null);
    ICategory category = appliancesProxy.getCategory(config.getCategoryPid(null));
    ILocation location = appliancesProxy.getLocation(config.getLocationPid(null));
    pw.println(
        (appliance.isDriver() ? "<b><u><br/>DRIVER" : "<b><u><br/>VIRTUAL")
            + " APPLIANCE</u>"
            + " (<a href=\""
            + appRoot
            + "/"
            + LABEL
            + "/config/"
            + appliancePid
            + (endPointId != null ? ("/" + endPointId) : "")
            + "\">Reload page</a>"
            + "&nbsp;&nbsp;&nbsp;<a href=\""
            + appRoot
            + "/"
            + LABEL
            + "/"
            + appliancePid
            + "\">Go to appliance details</a>)</br>"
            + "<br/>PID: "
            + appliance.getPid()
            + "<br/>TYPE: "
            + appliance.getDescriptor().getType()
            + ((name != null) ? "<br/>Name: " + name : "")
            + ((category != null) ? "<br/>Category: " + category.getName() : "")
            + ((location != null) ? "<br/>Location: " + location.getName() : "")
            + "</b><br/><hr/>");

    pw.println(
        "<br/><form name=\"ApplianceConfig\""
            + " action=\""
            + appRoot
            + "/"
            + LABEL
            + "/config/"
            + appliancePid
            + (endPointId != null ? ("/" + endPointId) : "")
            + "\" method=\"get\">");
    pw.println("<table id=\"ApplianceConfig\" class=\"nicetable\"><tbody>");
    pw.println("<tr><td width=\"50%\">");
    if (endPointId != null) {
      IEndPoint endPoint = appliance.getEndPoint(endPointId.intValue());
      pw.println(
          "<b>End point configuration (ID: "
              + endPointId
              + ", TYPE: "
              + endPoint.getType()
              + ")</b><br/>");
    } else {
      pw.println("<b>Appliance configuration</b><br/>");
    }
    pw.println("</b></td><td><input type=\"submit\" value=\"update\"/></td></tr>");

    name = config.getName(endPointId);
    String categoryPid = config.getCategoryPid(endPointId);
    String locationPid = config.getLocationPid(endPointId);
    pw.println(
        "<tr><td width=\"50%\">Name: </td><td><input type=\"text\" name=\"param\" size=\"30\" value=\""
            + name
            + "\"/></td></tr>");

    pw.println("</td></tr>");
    String pid = null;
    ICategory[] categories = appliancesProxy.getCategories();
    if (categories != null && categories.length > 0) {
      pw.println("<tr><td width=\"50%\">Category: </td><td><select name=\"param\">");
      for (int i = 0; i < categories.length; i++) {
        pid = categories[i].getPid();
        pw.println(
            "<option value=\""
                + pid
                + (pid.equals(categoryPid) ? "\" selected=\"selected\">" : "\" >")
                + categories[i].getName()
                + "</option>");
      }
      pw.println("</td></tr>");
    }

    ILocation[] locations = appliancesProxy.getLocations();
    if (locations != null && locations.length > 0) {
      pw.println("<tr><td width=\"50%\">Location: </td><td><select name=\"param\">");
      pid = null;
      for (int i = 0; i < locations.length; i++) {
        pid = locations[i].getPid();
        pw.println(
            "<option value=\""
                + pid
                + (pid.equals(locationPid) ? "\" selected=\"selected\">" : "\" >")
                + locations[i].getName()
                + "</option>");
      }
      pw.println("</td></tr>");
    }
    pw.println("</tbody></table></form>");
  }
  private void renderClusterCommands(
      String appRoot,
      IApplianceConfiguration config,
      IEndPoint endPoint,
      String clusterName,
      String methodName,
      String[] params,
      PrintWriter pw)
      throws SecurityException, InstantiationException, NoSuchFieldException,
          IllegalAccessException {
    IAppliance appliance = endPoint.getAppliance();
    String appliancePid = appliance.getPid();
    Integer endPointId = new Integer(endPoint.getId());
    String endPointType = endPoint.getType();
    String name = null;
    ICategory category = null;
    ILocation location = null;
    if (config != null) {
      name = config.getName(null);
      category = appliancesProxy.getCategory(config.getCategoryPid(null));
      location = appliancesProxy.getLocation(config.getLocationPid(null));
    }
    pw.println(
        (appliance.isDriver()
                ? "<br><b><u>DRIVER APPLIANCE CLUSTER</u>"
                : "<br><b>VIRTUAL APPLIANCE CLUSTER</u>")
            + "&nbsp;&nbsp;(<a <a href=\""
            + appRoot
            + "/"
            + LABEL
            + "/"
            + appliancePid
            + "/"
            + endPointId
            + "/"
            + clusterName
            + "\">Reload page</a>"
            + "&nbsp;&nbsp;&nbsp;<a href=\""
            + appRoot
            + "/"
            + LABEL
            + "/"
            + appliancePid
            + "\">Go to appliance details</a>)</br><hr/>");

    pw.println(
        "<br>APPLIANCE<br/>&nbsp;&nbsp;&nbsp;PID: "
            + appliance.getPid()
            + "<br/>&nbsp;&nbsp;&nbsp;TYPE: "
            + appliance.getDescriptor().getType()
            + ((name != null) ? "<br/>&nbsp;&nbsp;&nbsp;Name: " + name : "")
            + ((category != null) ? "<br/>&nbsp;&nbsp;&nbsp;Category: " + category.getName() : "")
            + ((location != null) ? "<br/>&nbsp;&nbsp;&nbsp;Location: " + location.getName() : "")
            + "<br/><br/>");

    if (config != null) {
      name = config.getName(endPointId);
      category = appliancesProxy.getCategory(config.getCategoryPid(endPointId));
      location = appliancesProxy.getLocation(config.getLocationPid(endPointId));
    }

    pw.println(
        "<br/>END POINT"
            + "<br/>&nbsp;&nbsp;&nbsp;ID: "
            + endPointId
            + "<br/>&nbsp;&nbsp;&nbsp;TYPE: "
            + endPointType
            + ((name != null) ? "<br/>&nbsp;&nbsp;&nbsp;Name: " + name : "")
            + ((category != null) ? "<br/>&nbsp;&nbsp;&nbsp;Category: " + category.getName() : "")
            + ((location != null) ? "<br/>&nbsp;&nbsp;&nbsp;Location: " + location.getName() : "")
            + "<br/>&nbsp;&nbsp;&nbsp;Cluster: "
            + clusterName
            + "</b><br/>");

    String result = null;
    long timestamp = System.currentTimeMillis();
    try {
      ISubscriptionParameters sp = null;
      if (methodName != null && methodName.equals(GET_ATTRIBUTE_SUBSCRIPTION_METHOD)) {
        sp =
            appliancesProxy.getAttributeSubscription(
                appliancePid, endPointId, clusterName, params[0]);
        result = TextConverter.getTextRepresentation(sp);
      } else if (methodName != null && methodName.equals(SET_ATTRIBUTE_SUBSCRIPTION_METHOD)) {
        if (!isEmpty(params[1]) || !isEmpty(params[2]) || !isEmpty(params[3])) {
          long minReportingInterval = isEmpty(params[1]) ? 0 : Long.parseLong(params[1]);
          long maxReportingInterval = isEmpty(params[2]) ? 0 : Long.parseLong(params[2]);
          double reportableChange = isEmpty(params[3]) ? 0 : Double.parseDouble(params[3]);
          sp =
              new SubscriptionParameters(
                  minReportingInterval, maxReportingInterval, reportableChange);
        }
        result =
            TextConverter.getTextRepresentation(
                appliancesProxy.setAttributeSubscription(
                    appliancePid, endPointId, clusterName, params[0], sp));
      } else if (methodName != null) {
        result =
            invokeClusterMethod(
                appliancesProxy,
                appliancePid,
                new Integer(endPointId),
                clusterName,
                methodName,
                params);
      }
    } catch (Exception e) {
      e.printStackTrace();
      result = "ERROR: " + e.getMessage();
    }

    Method[] methods;

    try {
      pw.print("<br/><br/><hr/><b><i>ATTRIBUTE SUBSCRIPTIONS:</i></b><hr/>");
      renderGetSubscriptionCommand(
          appRoot, appliancePid, endPointId, clusterName, methodName, result, pw);
      renderSetSubscriptionCommand(
          appRoot, appliancePid, endPointId, clusterName, methodName, result, pw);
      Map lastNotifiedAttributeValues =
          appliancesProxy.getLastNotifiedAttributeValues(appliancePid, endPointId, clusterName);
      if (lastNotifiedAttributeValues != null && lastNotifiedAttributeValues.size() > 0) {
        pw.println("<br/><table id=\"lastNotifiedAttributeValues\" class=\"nicetable\"><tbody>");
        pw.println(
            "<tr><td width=\"50%\"><b>Last notified attribute values:</b></td><td>&nbsp;</td></tr>");
        for (Iterator iterator = lastNotifiedAttributeValues.entrySet().iterator();
            iterator.hasNext(); ) {
          Entry entry = (Entry) iterator.next();
          pw.println(
              "<tr><td width=\"30%\"><b><font color=\"red\">"
                  + entry.getKey()
                  + ":</font></b></td><td><b><font color=\"red\">"
                  + TextConverter.getTextRepresentation(entry.getValue())
                  + "</font></b></td></tr>");
        }
      }
      pw.println("</tbody></table>");
      pw.print("<br/><br/><hr/><b><i>ATTRIBUTES AND COMMANDS:</i></b><hr/>");
      methods = Class.forName(clusterName).getMethods();
      //			methods = new Method[specificMethods.length + 2];
      //			methods[0] = IServiceCluster.class.getMethod(GET_ATTRIBUTE_SUBSCRIPTION_METHOD, new
      // Class[] {String.class, IEndPointRequestContext.class});
      //			methods[1] = IServiceCluster.class.getMethod(SET_ATTRIBUTE_SUBSCRIPTION_METHOD, new
      // Class[] {String.class, ISubscriptionParameters.class, IEndPointRequestContext.class});
      //			System.arraycopy(specificMethods, 0, methods, 2, specificMethods.length);
      Class[] parameters = null;
      for (int i = 0; i < methods.length; i++) {
        pw.println(
            "<br/><form name=\""
                + methods[i].getName()
                + i
                + "\""
                + " action=\""
                + appRoot
                + "/"
                + LABEL
                + "/"
                + appliancePid
                + "/"
                + endPointId
                + "/"
                + clusterName
                + "/"
                + methods[i].getName()
                + "#"
                + methods[i].getName()
                + "\" method=\"get\">");
        pw.println("<table id=\"" + methods[i].getName() + i + "\" class=\"nicetable\"><tbody>");
        pw.println(
            "<tr><td width=\"50%\"><b><a name=\""
                + methods[i].getName()
                + "\">"
                + methods[i].getName()
                + "</a></b></td><td><input type=\"submit\" value=\"invoke\"/></td></tr>");
        parameters = methods[i].getParameterTypes();
        for (int j = 0; j < parameters.length - 1; j++) {
          if (parameters[j].isArray()) {
            pw.println(
                "<tr><td width=\"50%\">Param"
                    + (j + 1)
                    + " (array["
                    + parameters[j].getComponentType().getName()
                    + "]):</td><td><input type=\"text\" name=\"param\" size=\"100\"/></td></tr>");
          } else {
            pw.println(
                "<tr><td width=\"50%\">Param"
                    + (j + 1)
                    + " ("
                    + parameters[j].getName()
                    + "):</td><td><input type=\"text\" name=\"param\" size=\"100\"/></td></tr>");
          }
        }
        pw.println("<input type=\"hidden\" name=\"ts\" value=\"" + timestamp + "\")");
        Class resultClass = methods[i].getReturnType();
        String resultClassStr;
        if (resultClass.isArray()) {
          resultClassStr = "array[" + resultClass.getComponentType().getName() + "]";
        } else {
          resultClassStr = resultClass.getName();
        }
        if (methodName != null && methods[i].getName().equals(methodName)) {
          pw.println(
              "<tr><td><b><font color=\"red\">Result ("
                  + resultClassStr
                  + "):</font></b></td><td><b><font color=\"red\">"
                  + formatResult(result)
                  + "</font></b></td></tr>");
        } else pw.println("<tr><td>Result (" + resultClassStr + "):</td><td>&nbsp;</td>");
        pw.println("</tbody></table></form>");
        pw.println("<br/><br/>");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 private void renderAppliance(
     String appRoot, boolean installing, boolean details, IAppliance appliance, PrintWriter pw) {
   String appliancePid = appliance.getPid();
   IApplianceConfiguration config = appliancesProxy.getApplianceConfiguration(appliancePid);
   IEndPoint[] endPoints = appliance.getEndPoints();
   if (endPoints != null && endPoints.length > 1) {
     String name = null;
     ICategory category = null;
     ILocation location = null;
     if (config != null) {
       name = config.getName(null);
       category = appliancesProxy.getCategory(config.getCategoryPid(null));
       location = appliancesProxy.getLocation(config.getLocationPid(null));
     }
     boolean isAvailable = appliance.isAvailable();
     if (isAvailable) {
       pw.println("<b>");
     } else {
       pw.println("<b><font color=\"gray\">");
     }
     if (!details) {
       pw.println((appliance.isDriver() ? "DRIVER APPLIANCE" : "VIRTUAL APPLIANCE"));
       pw.println(
           "&nbsp;(<a href=\""
               + appRoot
               + "/"
               + LABEL
               + "/"
               + appliancePid
               + "\">Details</a>"
               + (installing
                   ? "&nbsp;&nbsp;&nbsp;<a href=\""
                       + appRoot
                       + "/"
                       + LABEL
                       + "/install/"
                       + appliance.getPid()
                       + "\">Install</a>"
                   : "")
               + (appliance.isSingleton()
                   ? ")"
                   : ("&nbsp;&nbsp;&nbsp;<a href=\""
                       + appRoot
                       + "/"
                       + LABEL
                       + "/confirm/delete/"
                       + appliance.getPid()
                       + "\">Delete</a>)")));
     } else {
       pw.print(
           "<br/><u>APPLIANCE DETAILS</u>"
               + "&nbsp;&nbsp;(<a <a href=\""
               + appRoot
               + "/"
               + LABEL
               + "/"
               + appliancePid
               + "\">Reload page</a>&nbsp;&nbsp;&nbsp;<a href=\""
               + appRoot
               + "/"
               + LABEL
               + "\">Go to installed appliances</a>"
               + "&nbsp;&nbsp;&nbsp;<a href=\""
               + appRoot
               + "/"
               + LABEL
               + "/install\">Go to installing appliances</a>)</br><hr/>");
       pw.println((appliance.isDriver() ? "DRIVER APPLIANCE" : "VIRTUAL APPLIANCE"));
       if (!appliance.isSingleton()) {
         pw.println(
             "&nbsp;(<a href=\""
                 + appRoot
                 + "/"
                 + LABEL
                 + "/config/"
                 + appliancePid
                 + "\">Configuration</a>)");
       }
     }
     pw.println(
         "<br/>PID: "
             + appliance.getPid()
             + "<br/>TYPE: "
             + appliance.getDescriptor().getType()
             + ((name != null) ? "<br/>Name: " + name : "")
             + ((category != null) ? "<br/>Category: " + category.getName() : "")
             + ((location != null) ? "<br/>Location: " + location.getName() : "")
             + "</b><br/><br/>");
     if (isAvailable) {
       pw.println("</b>");
     } else {
       pw.println("</b></font>");
     }
     if (details) renderEndPoints(appRoot, config, endPoints, pw);
     pw.println("<hr>");
   }
 }