unsigned int MifareCommands::getSectorFromMAD(long aid, boost::shared_ptr<MifareKey> madKeyA)
	{
		unsigned int sector = static_cast<unsigned int>(-1);
		MifareAccessInfo::SectorAccessBits sab;
		
		if (!madKeyA->isEmpty())
		{
			getMifareChip()->getMifareProfile()->setKey(0, KT_KEY_A, madKeyA);
		}

		unsigned char madbuf[32];
		memset(madbuf, 0x00, sizeof(madbuf));

		if (!readSector(0, 1, madbuf, sizeof(madbuf), sab))
		{
			THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't read the MAD.");
		}
		
		unsigned char madcrc = calculateMADCrc(madbuf, sizeof(madbuf));
		if (madcrc != madbuf[0])
		{
			THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Bad MAD CRC.");
		}
		
		sector = findReferencedSector(aid, madbuf, sizeof(madbuf));

		if ((sector == static_cast<unsigned int>(-1)) && getChip()->getCardType() == "Mifare4K")
		{
			unsigned char madbuf2[48];
			memset(madbuf2, 0x00, sizeof(madbuf2));

			if (readSector(16, 0, madbuf2, sizeof(madbuf2), sab) != sizeof(madbuf2))
			{
				THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't read the MAD2.");
			}

			unsigned char mad2crc = calculateMADCrc(madbuf2, sizeof(madbuf2));
			if (mad2crc != madbuf2[0])
			{
				THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Bad MAD2 CRC.");
			}

			sector = findReferencedSector(aid, madbuf2, sizeof(madbuf2));

			if (sector != static_cast<unsigned int>(-1))
			{
				sector += 16;
			}
		}

		return sector;
	}
	void MifareCommands::setSectorToMAD(long aid, unsigned int sector, boost::shared_ptr<MifareKey> madKeyA, boost::shared_ptr<MifareKey> madKeyB)
	{
		MifareAccessInfo::SectorAccessBits sab;

		if (!madKeyA->isEmpty())
		{
			getMifareChip()->getMifareProfile()->setKey(0, KT_KEY_A, madKeyA);
			getMifareChip()->getMifareProfile()->setKey(16, KT_KEY_A, madKeyA);
		}

		if (madKeyB->isEmpty())
		{
			sab.setTransportConfiguration();
		}
		else
		{
			getMifareChip()->getMifareProfile()->setKey(0, KT_KEY_B, madKeyB);
			getMifareChip()->getMifareProfile()->setKey(16, KT_KEY_B, madKeyB);
			sab.setAReadBWriteConfiguration();
		}

		if (sector < 16)
		{
			if (sector == 0)
			{
				THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't make reference to the MAD itself.");
			}

			unsigned char madbuf[32];
			memset(madbuf, 0x00, sizeof(madbuf));

			if (readSector(0, 1, madbuf, sizeof(madbuf), sab) != sizeof(madbuf))
			{
				THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't read the MAD.");
			}
			
			madbuf[(sector*2)] = aid & 0xff;
			madbuf[sector*2 + 1] = (aid & 0xff00) >> 8;
			if (madbuf[1] == 0x00)
			{
				madbuf[1] = static_cast<unsigned char>(sector);
			}
			madbuf[0] = calculateMADCrc(madbuf, sizeof(madbuf));

			if (!writeSector(0, 1, madbuf, sizeof(madbuf), sab))
			{
				THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't write the MAD.");
			}
		}
		else
		{
			if (sector == 16)
    void MifareCommands::setSectorToMAD(long aid, unsigned int sector, std::shared_ptr<MifareKey> madKeyA, std::shared_ptr<MifareKey> madKeyB)
    {
        MifareAccessInfo::SectorAccessBits sab;

        if (!madKeyA->isEmpty())
        {
            getMifareChip()->getMifareProfile()->setKey(0, KT_KEY_A, madKeyA);
            getMifareChip()->getMifareProfile()->setKey(16, KT_KEY_A, madKeyA);
        }

        if (madKeyB->isEmpty())
        {
            sab.setTransportConfiguration();
        }
        else
        {
            getMifareChip()->getMifareProfile()->setKey(0, KT_KEY_B, madKeyB);
            getMifareChip()->getMifareProfile()->setKey(16, KT_KEY_B, madKeyB);
            sab.setAReadBWriteConfiguration();
        }

        if (sector < 16)
        {
            if (sector == 0)
            {
                THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't make reference to the MAD itself.");
            }

			std::vector<unsigned char> madbuf = readSector(0, 1, sab);
			if (!madbuf.size())
            {
                THROW_EXCEPTION_WITH_LOG(LibLogicalAccessException, "Can't read the MAD.");
            }

            madbuf[(sector * 2)] = aid & 0xff;
            madbuf[sector * 2 + 1] = (aid & 0xff00) >> 8;
            if (madbuf[1] == 0x00)
            {
                // BCD Nibble representation
                madbuf[1] = static_cast<unsigned char>(sector % 10);
                if (sector >= 10)
                {
                    madbuf[1] |= 0x10;
                }
            }
            madbuf[0] = calculateMADCrc(&madbuf[0], madbuf.size());

            writeSector(0, 1, madbuf, sab);
        }
        else
        {
            if (sector == 16)