/**
   * Accepts operation to map on the matrix
   *
   * @param operation
   * @return
   */
  private void mapOperation(Operation operation) {
    Operand[] opInputs = operation.getInputs();
    Operand[] opOutputs = operation.getOutputs();
    // Fu data
    Operand[] fuInputs = new Operand[opInputs.length];
    // Operand[] fuOutputs = new Operand[opOutputs.length];

    // Check inputs
    for (int i = 0; i < opInputs.length; i++) {
      if (opInputs[i] == null) {
        continue;
      }

      if (opInputs[i].getOpType() == Operand.OpType.literal) {
        fuInputs[i] = opInputs[i];
        continue;
      }

      if (opInputs[i].getOpType() == Operand.OpType.register) {
        // This can be combine in one class
        String register = opInputs[i].getValue();
        Operand op = null;
        // Check if literals table has this register
        op = literalsTable.get(register);
        // Check if current producers have this register
        if (op == null) {
          op = currentProducers.get(register);
        }

        if (op == null) {
          liveIns.add(register);
        } else {
          fuInputs[i] = op;
        }

        continue;
      }

      System.out.println("mapOperation Error: shouldn't be here");
    }

    boolean isMemoryOperation = Memory.isMemoryOperation.contains(operation.getOperation());

    int fromLine = 0;
    // 1 Memory operation per line
    if (isMemoryOperation) {
      // Check last line used by memory operation
      fromLine = lastLineUseByMemoryOperation + 1;
    }

    int destinationLine = calculateDestinationLine(fuInputs, fromLine);

    int destinationCol = matrix.getFirstAvaliableColumn(destinationLine);
    Fu mappedOp = matrix.mapNewOperation(destinationLine, destinationCol, operation, fuInputs);

    processOutput(opOutputs, mappedOp.getOutput());

    // Add, in the end
    if (feedDistance > 0) {
      for (int i = 0; i < fuInputs.length; i++) {
        Fu newMove = addMoveOperations(destinationLine, fuInputs[i]);
        if (mappingFailed) {
          return;
        }
      }
    }

    // Update memory line
    /*
    if(isMemoryOperation) {
       // Check last line used by memory operation
       lastLineUseByMemoryOperation = destinationLine;
    }
     */
    // Scenario 2: parallel loads, serial stores
    if (Memory.isStore.contains(operation.getOperation())) {
      lastLineUseByMemoryOperation = destinationLine;
    }
  }