/**
   * Save color result which is computed by AGG grammar.
   *
   * @param gra
   * @param outFileName must end with ".aggcol"
   */
  public void saveAGGColor(GraGra gra, String outFileName) {
    if (outputFileName.endsWith(".aggcol")) {

      final List<Node> edges = new Vector<Node>();

      final List<Node> nodes = new Vector<Node>();
      nodes.addAll(gragra.getGraph(this.indx).getNodesSet());
      for (int i = 0; i < nodes.size(); i++) {
        final Node n = nodes.get(i);
        if (n.getType().getName().equals("Node")) {

        } else if (n.getType().getName().equals("Edge")) {
          edges.add(n);
          nodes.remove(i);
          i--;
        } else {
          nodes.remove(i);
          i--;
        }
      }

      final File f = new File(outputFileName);
      ByteArrayOutputStream baOut = null;
      FileOutputStream fos = null;
      try {
        fos = new FileOutputStream(f);

        // write comment
        baOut = new ByteArrayOutputStream();
        String comment = "c AGG Color\n";
        // put in out stream and file
        baOut.write(comment.getBytes());
        fos.write(baOut.toByteArray());
        baOut.flush();

        // write problem
        baOut = new ByteArrayOutputStream();
        String problem = "p edge ";
        problem = problem.concat(String.valueOf(nodes.size()));
        problem = problem.concat(" ");
        problem = problem.concat(String.valueOf(edges.size()));
        problem = problem.concat("\n");
        // put in out stream and file
        baOut.write(problem.getBytes());
        fos.write(baOut.toByteArray());
        baOut.flush();

        for (int i = 0; i < nodes.size(); i++) {
          final Node n = nodes.get(i);
          ValueTuple val = (ValueTuple) n.getAttribute();
          String color = ((ValueMember) val.getMemberAt("color")).getExprAsText();
          color = color.concat(" ");

          // write color
          baOut = new ByteArrayOutputStream();
          baOut.write(color.getBytes());
          fos.write(baOut.toByteArray());
          baOut.flush();
        }
      } catch (IOException e) {
      }
    }
  }
  /**
   * Import a ColorGraph which is specified by String colorFileName into the by index specified
   * Graph of the specified GraGra.
   *
   * @param gra
   * @param graph
   * @param colorFileName is the full file name and must end with ".res"
   */
  private boolean importColorGraph2AGG(final GraGra gra, final Graph graph) {
    if (this.colorFileName.endsWith(".res")) {

      //			final List<Node> edges = new Vector<Node>();

      final List<Node> nodes = new Vector<Node>();
      nodes.addAll(graph.getNodesSet());

      for (int i = 0; i < nodes.size(); i++) {
        final Node n = nodes.get(i);
        if (n.getType().getName().equals("Node")) {

        } else if (n.getType().getName().equals("Edge")) {
          //					edges.add(n);
          nodes.remove(i);
          i--;
        } else {
          nodes.remove(i);
          i--;
        }
      }

      final File f = new File(this.colorFileName);
      FileInputStream fos = null;
      byte b[] = new byte[1024];
      int count = 0;

      try {
        fos = new FileInputStream(f);
        while (count != -1) {
          count = fos.read(b);
          if (count != -1) {
            String s = new String(b);

            int lineEnd = s.indexOf("\n");
            while (lineEnd != -1) {
              String str = s.substring(0, lineEnd);
              s = s.substring(lineEnd + 1, s.length() - 1);
              lineEnd = s.indexOf("\n");

              if (lineEnd == -1) {
                while (str.charAt(0) == ' ') {
                  str = str.substring(1, str.length());
                }

                String[] str_e = str.split("   ");

                for (int i = 0; i < str_e.length; i++) {
                  String color = str_e[i].trim();

                  Node node = nodes.get(i);
                  if (node.getAttribute() != null) {
                    ValueTuple val = (ValueTuple) node.getAttribute();
                    ValueMember mem = val.getValueMemberAt("color");
                    if (mem == null) mem = val.getValueMemberAt("Color");
                    if (mem != null) mem.setExprAsText(color);
                  }
                }
              }
            }
          }
        }
        return true;

      } catch (IOException e) {
      }
    }
    return false;
  }
  /**
   * Search the host graph of the grammar for subgraph with Node<--Edge-->Node structure, where each
   * edge starts at node Edge and ends at node Node. Save this subgraph in GraphColor format.
   *
   * @param gra
   * @param outFileName must end with ".col"
   */
  public void saveAGGNodeEdge2ColorGraph(GraGra gra, String outFileName) {
    if (outputFileName.endsWith(".col")) {

      final List<Node> edges = new Vector<Node>();

      final List<Node> nodes = new Vector<Node>();
      nodes.addAll(gragra.getGraph(this.indx).getNodesSet());
      for (int i = 0; i < nodes.size(); i++) {
        final Node n = nodes.get(i);
        if (n.getType().getName().equals("Node")) {

        } else if (n.getType().getName().equals("Edge")) {
          edges.add(n);
          nodes.remove(i);
          i--;
        } else {
          nodes.remove(i);
          i--;
        }
      }

      final File f = new File(outputFileName);
      ByteArrayOutputStream baOut = null;
      FileOutputStream fos = null;
      try {
        fos = new FileOutputStream(f);

        // write comment
        baOut = new ByteArrayOutputStream();
        String comment = "c AGG to Color Graph (.col)\n";
        // put in out stream and file
        baOut.write(comment.getBytes());
        fos.write(baOut.toByteArray());
        baOut.flush();

        // write problem
        baOut = new ByteArrayOutputStream();
        String problem = "p edge ";
        problem = problem.concat(String.valueOf(nodes.size()));
        problem = problem.concat(" ");
        problem = problem.concat(String.valueOf(edges.size()));
        problem = problem.concat("\n");
        // put in out stream and file
        baOut.write(problem.getBytes());
        fos.write(baOut.toByteArray());
        baOut.flush();

        for (int i = 0; i < edges.size(); i++) {
          final Node en = edges.get(i);

          Iterator<Arc> outs = en.getOutgoingArcs();
          if (outs.hasNext()) {
            final Arc a = outs.next();
            int index = nodes.indexOf(a.getTarget()) + 1;

            while (outs.hasNext()) {
              final Arc aj = outs.next();
              int indxj = nodes.indexOf(aj.getTarget()) + 1;
              String str = "e ";
              str = str.concat(String.valueOf(index)).concat(" ");
              str = str.concat(String.valueOf(indxj).concat("\n"));

              // write edge line
              baOut = new ByteArrayOutputStream();
              baOut.write(str.getBytes());
              fos.write(baOut.toByteArray());
              baOut.flush();
            }
          }
        }
      } catch (IOException e) {
      }
    }
  }