contract AutoIncrementCoinageSnapshotFactory {

  /// @notice Update the DApp by creating a new token with new functionalities
  ///  the msg.sender becomes the controller of this clone token
  /// @param _parentToken Address of the token being cloned
  /// @param _snapshotBlock Block of the parent token that will
  ///  determine the initial distribution of the clone token
  /// @param _tokenName Name of the new token
  /// @param _tokenSymbol Token Symbol for the new token
  /// @param _transfersEnabled If true, tokens will be able to be transferred
  /// @return The address of the new token contract
  function createCloneToken(
    address payable _parentToken,
    uint _snapshotBlock,
    string memory _tokenName,
    string memory _tokenSymbol,
    uint _factor,
    uint _factorIncrement,
    bool _transfersEnabled
  ) public returns (AutoIncrementCoinageSnapshot) {
    AutoIncrementCoinageSnapshot newToken = new AutoIncrementCoinageSnapshot(
      address(uint160(address(this))),
      _parentToken,
      _snapshotBlock,
      _tokenName,
      _tokenSymbol,
      _factor,
      _factorIncrement,
      _transfersEnabled
      );

    newToken.changeController(msg.sender);
    return newToken;
  }
}
////////////////
/// @dev This contract is used to generate clone contracts from a contract.
///  In solidity this is the way to create a contract from a contract of the
///  same class
function createCloneToken(
  address payable _parentToken,
  uint _snapshotBlock,
  string memory _tokenName,
  string memory _tokenSymbol,
  uint _factor,
  uint _factorIncrement,
  bool _transfersEnabled
) public returns (AutoIncrementCoinageSnapshot) {
  AutoIncrementCoinageSnapshot newToken = new AutoIncrementCoinageSnapshot(
    address(uint160(address(this))),
    _parentToken,
    _snapshotBlock,
    _tokenName,
    _tokenSymbol,
    _factor,
    _factorIncrement,
    _transfersEnabled
    );

  newToken.changeController(msg.sender);
  return newToken;
}

/// @notice Update the DApp by creating a new token with new functionalities
///  the msg.sender becomes the controller of this clone token
/// @param _parentToken Address of the token being cloned
/// @param _snapshotBlock Block of the parent token that will
///  determine the initial distribution of the clone token
/// @param _tokenName Name of the new token
/// @param _tokenSymbol Token Symbol for the new token
/// @param _transfersEnabled If true, tokens will be able to be transferred
/// @return The address of the new token contract