//====================================================================
bool ConnectedComponentPacking::run() {

  LayoutProperty *layout = NULL;
  SizeProperty *size = NULL;
  DoubleProperty *rotation = NULL;
  string complexity("auto");

  workingGraph = graph->addCloneSubGraph("workingGraph");

  if ( dataSet!=NULL ) {
    dataSet->get("coordinates", layout);
    getNodeSizePropertyParameter(dataSet, size);
    dataSet->get("rotation", rotation);
    StringCollection complexityCol;

    if (dataSet->get("complexity", complexityCol))
      complexity = complexityCol.getCurrentString();
  }

  if (layout==NULL)
    layout = workingGraph->getProperty<LayoutProperty>("viewLayout");

  if (size==NULL)
    size = workingGraph->getProperty<SizeProperty>("viewSize");

  if (rotation==NULL)
    rotation = workingGraph->getProperty<DoubleProperty>("viewRotation");

  if (complexity=="none")
    complexity = "auto";

  // compute the connected components's subgraphs
  std::vector<std::set<node> > components;
  ConnectedTest::computeConnectedComponents(workingGraph, components);

  for (unsigned int i = 0; i < components.size(); ++i) {
    workingGraph->inducedSubGraph(components[i]);
  }

  vector<Rectangle<float> > rectangles;
  Iterator<Graph *> *it = workingGraph->getSubGraphs();

  while(it->hasNext()) {
    Graph *sg = it->next();
    BoundingBox tmp = tlp::computeBoundingBox(sg, layout, size, rotation);
    Rectangle<float> tmpRec;
    tmpRec[1][0] = tmp[1][0] + spacing;
    tmpRec[1][1] = tmp[1][1] + spacing;
    tmpRec[0][0] = tmp[0][0] + spacing;
    tmpRec[0][1] = tmp[0][1] + spacing;
    assert(tmpRec.isValid());
    rectangles.push_back(tmpRec);
  }

  delete it;

  if (complexity == "auto") {
    if (rectangles.size()<25) {
      complexity="n5";
    }
    else if (rectangles.size()<50) {
      complexity="n4logn";
    }
    else if (rectangles.size()<100) {
      complexity="n4";
    }
    else if (rectangles.size()<150) {
      complexity="n3logn";
    }
    else if (rectangles.size()<250) {
      complexity="n3";
    }
    else if (rectangles.size()<500) {
      complexity="n2logn";
    }
    else if (rectangles.size()<1000) {
      complexity="n2";
    }
    else if (rectangles.size()<5000) {
      complexity="nlogn";
    }
    else
      complexity="n";
  }

  vector<Rectangle<float> > rectanglesBackup(rectangles);
  RectanglePackingLimitRectangles(rectangles, complexity.c_str(), pluginProgress);
  Iterator<node> *itN = graph->getNodes();

  while(itN->hasNext()) {
    node n = itN->next();
    layoutResult->setNodeValue(n, layout->getNodeValue(n));
  }

  delete itN;
  Iterator<edge> *itE = graph->getEdges();

  while(itE->hasNext()) {
    edge e = itE->next();
    layoutResult->setEdgeValue(e, layout->getEdgeValue(e));
  }

  delete itE;
  unsigned int i = 0;
  it = workingGraph->getSubGraphs();

  while(it->hasNext()) {
    Graph *sg = it->next();
    Coord move(rectangles[i][0][0]-rectanglesBackup[i][0][0], rectangles[i][0][1]-rectanglesBackup[i][0][1], 0);
    layoutResult->translate(move, sg);
    ++i;
  }

  delete it;
  graph->delAllSubGraphs(workingGraph);

  return true;
}
///===========================================================
bool ReachableSubGraphSelection::run() {
  unsigned int maxDistance = 5;
  StringCollection edgeDirectionCollecion;
  EDGE_TYPE edgeDirection=DIRECTED;
  BooleanProperty * startNodes=graph->getProperty<BooleanProperty>("viewSelection");

  if ( dataSet!=NULL) {
    dataSet->get("distance", maxDistance);

    //Get the edge orientation
    if(dataSet->get("edges direction",edgeDirectionCollecion)) {
      if(edgeDirectionCollecion.getCurrentString() == edgesDirectionLabels[0]) {
        edgeDirection = DIRECTED;
      }
      else if(edgeDirectionCollecion.getCurrentString()== edgesDirectionLabels[1]) {
        edgeDirection = INV_DIRECTED;
      }
      else if(edgeDirectionCollecion.getCurrentString()== edgesDirectionLabels[2]) {
        edgeDirection = UNDIRECTED;
      }
    }
    else {
      //If the new parameter is not defined search for the old one.
      int direction=0;

      if(dataSet->get("direction",direction)) {
        switch(direction) {
        case 0:
          edgeDirection = DIRECTED;
          break;

        case 1:
          edgeDirection = INV_DIRECTED;
          break;

        case 2:
          edgeDirection = UNDIRECTED;
        }
      }
    }

    dataSet->get("startingnodes", startNodes);
  }

  result->setAllEdgeValue(false);
  result->setAllNodeValue(false);

  if (startNodes) {
    Iterator<node>* itN = startNodes->getNodesEqualTo(true);
    std::set<node> reachables;

    // iterate on startNodes add them and their reachables
    while (itN->hasNext()) {
      node current = itN->next();
      reachables.insert(current);
      reachableNodes(graph, current, reachables, maxDistance,
                     edgeDirection);
    }

    delete itN;

    std::set<node>::const_iterator itr = reachables.begin();
    std::set<node>::const_iterator ite = reachables.end();

    // select nodes
    while (itr != ite) {
      result->setNodeValue((*itr), true);
      ++itr;
    }

    // select corresponding edges
    Iterator<edge> *itE = graph->getEdges();

    while(itE->hasNext()) {
      edge e = itE->next();
      const std::pair<node, node>& ends = graph->ends(e);

      if (result->getNodeValue(ends.first) &&
          result->getNodeValue(ends.second))
        result->setEdgeValue(e, true);
    }

    delete itE;
  }

  return true;
}