text:
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/Debian/dcs/goroutinez"
	"github.com/Debian/dcs/index"
	"github.com/Debian/dcs/varz"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"strings"
	"time"
	"unicode/utf8"
)

var (
	listenAddress = flag.String("listen_address",
		":21010",
		"listen address ([host]:port)")

	unpackedPath = flag.String("unpacked_path",
		"/dcs-ssd/unpacked/",
		"Path to the unpacked sources")

	cpuProfile = flag.String("cpuprofile",
		"",
		"write cpu profile to this file")

	tmpdir string

	indexQueue chan string
	mergeQueue chan bool
)

// Accepts arbitrary files for a given package and starts unpacking once a .dsc
// file is uploaded. E.g.:
//
// curl -X PUT --data-binary @i3-wm_4.7.2-1.debian.tar.xz \
//     http://localhost:21010/import/i3-wm_4.7.2-1/i3-wm_4.7.2-1.debian.tar.xz
// curl -X PUT --data-binary @i3-wm_4.7.2.orig.tar.bz2 \
//     http://localhost:21010/import/i3-wm_4.7.2-1/i3-wm_4.7.2.orig.tar.bz2
// curl -X PUT --data-binary @i3-wm_4.7.2-1.dsc \
//     http://localhost:21010/import/i3-wm_4.7.2-1/i3-wm_4.7.2-1.dsc
//
// All the files are stored in the same directory and after the .dsc is stored,
// the package is unpacked with dpkg-source, then indexed.
func importPackage(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	path := r.URL.Path[len("/import/"):]
	pkg := filepath.Dir(path)
	filename := filepath.Base(path)

	err := os.Mkdir(filepath.Join(tmpdir, pkg), 0755)
	if err != nil && !os.IsExist(err) {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		varz.Increment("failed-package-imports")
		return
	}

	file, err := os.Create(filepath.Join(tmpdir, path))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		varz.Increment("failed-package-imports")
		return
	}
	defer file.Close()
	written, err := io.Copy(file, r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		varz.Increment("failed-package-imports")
		return
	}
	log.Printf("Wrote %d bytes into %s\n", written, path)

	fmt.Fprintf(w, "thank you for sending file %s for package %s!\n", filename, pkg)
	if strings.HasSuffix(filename, ".dsc") {
		indexQueue <- path
	}

	varz.Increment("successful-package-imports")
}

// Tries to start a merge and errors in case one is already in progress.
func mergeOrError(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	select {
	case mergeQueue <- true:
		fmt.Fprintf(w, "Merge started.")
	default:
		http.Error(w, "Merge already in progress, please try again later.", http.StatusInternalServerError)
	}
}

func packageNames() []string {
	var names []string

	file, err := os.Open(*unpackedPath)
	// If the directory does not yet exist, we just return an empty list of
	// packages.
	if err != nil && !os.IsNotExist(err) {
		log.Fatal(err)
	}
	if err == nil {
		defer file.Close()
		names, err = file.Readdirnames(-1)
		if err != nil {
			log.Fatal(err)
		}
	}

	return names
}

func listPackages(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()

	names := packageNames()

	type ListPackageReply struct {
		Packages []string
	}

	var reply ListPackageReply
	reply.Packages = make([]string, 0, len(names))
	for _, name := range names {
		if strings.HasSuffix(name, ".idx") && name != "full.idx" {
			reply.Packages = append(reply.Packages, name[:len(name)-len(".idx")])
		}
	}

	jsonReply, err := json.Marshal(&reply)
	if err != nil {
		http.Error(w, fmt.Sprintf("Serialization error: %v", err), http.StatusInternalServerError)
		return
	}

	if _, err := w.Write(jsonReply); err != nil {
		log.Printf("Could not send listPackages reply: %v\n", err)
	}
}

func garbageCollect(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	pkg := r.FormValue("package")
	if pkg == "" {
		http.Error(w, "No ?package= provided", http.StatusInternalServerError)
		return
	}

	names := packageNames()
	found := false
	for _, name := range names {
		// Note that the logic is inverted in comparison to earlier in the
		// code: for listPackages, we want to only return packages that have
		// been unpacked and indexed (so we strip .idx), but for garbage
		// collection, we also want to garbage collect packages that were not
		// indexed for some reason, so we ignore .idx.
		if name == pkg && !strings.HasSuffix(name, ".idx") {
			found = true
			break
		}
	}

	if !found {
		http.Error(w, "No such package", http.StatusInternalServerError)
		return
	}

	if err := os.RemoveAll(filepath.Join(*unpackedPath, pkg)); err != nil {
		http.Error(w, fmt.Sprintf("Could not garbage collect package %q: %v", pkg, err), http.StatusInternalServerError)
		return
	}

	if err := os.Remove(filepath.Join(*unpackedPath, pkg+".idx")); err != nil {
		http.Error(w, fmt.Sprintf("Could not garbage collect package index for %q: %v", pkg, err), http.StatusInternalServerError)
		return
	}

	varz.Increment("successful-garbage-collects")
}

// Merges all packages in *unpackedPath into a big index shard.
func mergeToShard() {
	names := packageNames()
	indexFiles := make([]string, 0, len(names))
	for _, name := range names {
		if strings.HasSuffix(name, ".idx") && name != "full.idx" {
			indexFiles = append(indexFiles, filepath.Join(*unpackedPath, name))
		}
	}

	varz.Set("index-files", uint64(len(indexFiles)))

	log.Printf("Got %d index files\n", len(indexFiles))
	if len(indexFiles) == 1 {
		return
	}
	tmpIndexPath, err := ioutil.TempFile(*unpackedPath, "newshard")
	if err != nil {
		log.Fatal(err)
	}

	if *cpuProfile != "" {
		f, err := os.Create(*cpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	t0 := time.Now()
	index.ConcatN(tmpIndexPath.Name(), indexFiles...)
	t1 := time.Now()
	log.Printf("merged in %v\n", t1.Sub(t0))
	//for i := 1; i < len(indexFiles); i++ {
	//	log.Printf("merging %s with %s\n", indexFiles[i-1], indexFiles[i])
	//	t0 := time.Now()
	//	index.Concat(tmpIndexPath.Name(), indexFiles[i-1], indexFiles[i])
	//	t1 := time.Now()
	//	log.Printf("merged in %v\n", t1.Sub(t0))
	//}
	log.Printf("merged into shard %s\n", tmpIndexPath.Name())

	// If full.idx does not exist (i.e. on initial deployment), just move the
	// new index to full.idx, the dcs-index-backend will not be running anyway.
	fullIdxPath := filepath.Join(*unpackedPath, "full.idx")
	if _, err := os.Stat(fullIdxPath); os.IsNotExist(err) {
		if err := os.Rename(tmpIndexPath.Name(), fullIdxPath); err != nil {
			log.Fatal(err)
		}
		return
	}

	varz.Increment("successful-merges")

	// Replace the current index with the newly created index.
	resp, err := http.Get(fmt.Sprintf("http://localhost:28081/replace?shard=%s", filepath.Base(tmpIndexPath.Name())))
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		body, _ := ioutil.ReadAll(resp.Body)
		log.Fatalf("dcs-index-backend /replace response: %+v (body: %s)\n", resp, body)
	}
}

func indexPackage(pkg string) {
	log.Printf("Indexing %s\n", pkg)
	unpacked := filepath.Join(tmpdir, pkg, pkg)
	if err := os.MkdirAll(*unpackedPath, os.FileMode(0755)); err != nil {
		log.Fatalf("Could not create directory: %v\n", err)
	}

	// Write to a temporary file first so that merges can happen at the same
	// time. If we don't do that, merges will try to use incomplete index
	// files, which are interpreted as corrupted.
	tmpIndexPath := filepath.Join(*unpackedPath, pkg+".tmp")
	index := index.Create(tmpIndexPath)
	// +1 because of the / that should not be included in the index.
	stripLen := len(filepath.Join(tmpdir, pkg)) + 1

	filepath.Walk(unpacked,
		func(path string, info os.FileInfo, err error) error {
			if dir, filename := filepath.Split(path); filename != "" {
				skip := ignored(info, dir, filename)
				if skip && info.IsDir() {
					if err := os.RemoveAll(path); err != nil {
						log.Fatalf("Could not remove directory %q: %v\n", path, err)
					}
					return filepath.SkipDir
				}
				if skip && !info.IsDir() {
					if err := os.Remove(path); err != nil {
						log.Fatalf("Could not remove file %q: %v\n", path, err)
					}
					return nil
				}
			}

			if info == nil || !info.Mode().IsRegular() {
				return nil
			}

			// Some filenames (e.g.
			// "xblast-tnt-levels_20050106-2/reconstruct\xeeon2.xal") contain
			// invalid UTF-8 and will break when sending them via JSON later
			// on. Filter those out early to avoid breakage.
			if !utf8.ValidString(path) {
				log.Printf("Skipping due to invalid UTF-8: %s\n", path)
				return nil
			}

			if err := index.AddFile(path, path[stripLen:]); err != nil {
				if err := os.Remove(path); err != nil {
					log.Fatalf("Could not remove file %q: %v\n", path, err)
				}
			} else {
				// Copy this file out of /tmp to our unpacked directory.
				outputPath := filepath.Join(*unpackedPath, path[stripLen:])
				if err := os.MkdirAll(filepath.Dir(outputPath), os.FileMode(0755)); err != nil {
					log.Fatalf("Could not create directory: %v\n", err)
				}
				output, err := os.Create(outputPath)
				if err != nil {
					log.Fatalf("Could not create output file %q: %v\n", outputPath, err)
				}
				defer output.Close()
				input, err := os.Open(path)
				if err != nil {
					log.Fatalf("Could not open input file %q: %v\n", path, err)
				}
				defer input.Close()
				if _, err := io.Copy(output, input); err != nil {
					log.Fatalf("Could not copy %q to %q: %v\n", path, outputPath, err)
				}
			}
			return nil
		})

	index.Flush()

	finalIndexPath := filepath.Join(*unpackedPath, pkg+".idx")
	if err := os.Rename(tmpIndexPath, finalIndexPath); err != nil {
		log.Fatal(err)
	}
	varz.Increment("successful-package-indexes")
}

// This goroutine reads package names from the indexQueue channel, unpacks the
// package, deletes all unnecessary files and indexes it.
// By default, the number of simultaneous goroutines running this function is
// equal to your number of CPUs.
func unpackAndIndex() {
	for {
		dscPath := <-indexQueue
		pkg := filepath.Dir(dscPath)
		log.Printf("Unpacking %s\n", pkg)
		unpacked := filepath.Join(tmpdir, pkg, pkg)

		// Delete previous attempts, if any.
		if err := os.RemoveAll(unpacked); err != nil {
			log.Printf("removing unpacked dir: %v\n", err)
		}

		cmd := exec.Command("dpkg-source", "--no-copy", "--no-check", "-x",
			filepath.Join(tmpdir, dscPath), unpacked)
		// Just display dpkg-source's stderr in our process's stderr.
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			log.Printf("Skipping package %s: %v\n", pkg, err)
			varz.Increment("failed-dpkg-source-extracts")
			continue
		}

		varz.Increment("successful-dpkg-source-extracts")
		indexPackage(pkg)
		os.RemoveAll(filepath.Join(tmpdir, pkg))
	}
}

func main() {
	flag.Parse()

	// Allow as many concurrent unpackAndIndex goroutines as we have cores.
	runtime.GOMAXPROCS(runtime.NumCPU())

	varz.Set("failed-dpkg-source-extracts", 0)
	varz.Set("failed-package-imports", 0)
	varz.Set("successful-dpkg-source-extracts", 0)
	varz.Set("successful-garbage-collects", 0)
	varz.Set("successful-merges", 0)
	varz.Set("successful-package-imports", 0)
	varz.Set("successful-package-indexes", 0)

	setupFilters()

	var err error
	tmpdir, err = ioutil.TempDir("", "dcs-importer")
	if err != nil {
		log.Fatal(err)
	}

	indexQueue = make(chan string)
	mergeQueue = make(chan bool)

	for i := 0; i < runtime.NumCPU(); i++ {
		go unpackAndIndex()
	}

	go func() {
		for _ = range mergeQueue {
			mergeToShard()
		}
	}()

	http.HandleFunc("/import/", importPackage)
	http.HandleFunc("/merge", mergeOrError)
	http.HandleFunc("/listpkgs", listPackages)
	http.HandleFunc("/garbagecollect", garbageCollect)
	http.HandleFunc("/varz", varz.Varz)
	http.HandleFunc("/goroutinez", goroutinez.Goroutinez)

	log.Fatal(http.ListenAndServe(*listenAddress, nil))
}


text:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Protocols.TestTools.StackSdk.Asn1;

namespace Microsoft.Protocols.TestTools.StackSdk.Security.Spng
{
    /*
    NegTokenResp ::= SEQUENCE {
       negState       [0] ENUMERATED {
           accept-completed    (0),
           accept-incomplete   (1),
           reject              (2),
           request-mic         (3)
       }                                 OPTIONAL,
         -- REQUIRED in the first reply from the target
       supportedMech   [1] MechType      OPTIONAL,
         -- present only in the first reply from the target
       responseToken   [2] OCTET STRING  OPTIONAL,
       mechListMIC     [3] OCTET STRING  OPTIONAL,
       ...
   }
    */
    public class NegTokenResp : Asn1Sequence
    {
        [Asn1Field(0, Optional = true), Asn1Tag(Asn1TagType.Context, 0)]
        public NegState negState { get; set; }

        [Asn1Field(1, Optional = true), Asn1Tag(Asn1TagType.Context, 1)]
        public MechType supportedMech { get; set; }

        [Asn1Field(2, Optional = true), Asn1Tag(Asn1TagType.Context, 2)]
        public Asn1OctetString responseToken { get; set; }

        [Asn1Field(3, Optional = true), Asn1Tag(Asn1TagType.Context, 3)]
        public Asn1OctetString mechListMIC { get; set; }

        public NegTokenResp()
        {
            this.negState = null;
            this.supportedMech = null;
            this.responseToken = null;
            this.mechListMIC = null;
        }

        public NegTokenResp(
         NegState negState,
         MechType supportedMech,
         Asn1OctetString responseToken,
         Asn1OctetString mechListMIC)
        {
            this.negState = negState;
            this.supportedMech = supportedMech;
            this.responseToken = responseToken;
            this.mechListMIC = mechListMIC;
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
namespace Neat.Infrastructure.Security.Model.Response
{
    public class AuthorizationResponse
    {
        public string UserId { get; set; }
        public bool IsAuthorized { get; set; }
        public string AuthorizationMessage { get; set; }
        public object SecuredObject { get; set; }

        public override string ToString()
        {
            return string.Format("UserId: {0}, IsAuthorized: {1}, AuthorizationMessage: {2}, SecuredObject: {3}", UserId, IsAuthorized, AuthorizationMessage, SecuredObject);
        }
    }
}


text:
#include "masstorage.h"

const uint8_t BulkOnly::epDataInIndex = 1;
const uint8_t BulkOnly::epDataOutIndex = 2;
const uint8_t BulkOnly::epInterruptInIndex = 3;

////////////////////////////////////////////////////////////////////////////////

// Interface code

////////////////////////////////////////////////////////////////////////////////

/**
 * Get the capacity of the media
 *
 * @param lun Logical Unit Number
 * @return media capacity
 */
uint32_t BulkOnly::GetCapacity(uint8_t lun) {
        if (LUNOk[lun])
                return CurrentCapacity[lun];
        return 0LU;
}

/**
 * Get the sector (block) size used on the media
 *
 * @param lun Logical Unit Number
 * @return media sector size
 */
uint16_t BulkOnly::GetSectorSize(uint8_t lun) {
        if (LUNOk[lun])
                return CurrentSectorSize[lun];
        return 0U;
}

/**
 * Test if LUN is ready for use
 *
 * @param lun Logical Unit Number
 * @return true if LUN is ready for use
 */
bool BulkOnly::LUNIsGood(uint8_t lun) {
        return LUNOk[lun];
}

/**
 * Test if LUN is write protected
 *
 * @param lun Logical Unit Number
 * @return cached status of write protect switch
 */
boolean BulkOnly::WriteProtected(uint8_t lun) {
        return WriteOk[lun];
}

/**
 * Wrap and execute a SCSI CDB with length of 6
 *
 * @param cdb CDB to execute
 * @param buf_size Size of expected transaction
 * @param buf Buffer
 * @param dir MASS_CMD_DIR_IN | MASS_CMD_DIR_OUT
 * @return
 */
uint8_t BulkOnly::SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir) {
        // promote buf_size to 32bits.
        CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir);
        //SetCurLUN(cdb->LUN);
        return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
}

/**
 * Wrap and execute a SCSI CDB with length of 10
 *
 * @param cdb CDB to execute
 * @param buf_size Size of expected transaction
 * @param buf Buffer
 * @param dir MASS_CMD_DIR_IN | MASS_CMD_DIR_OUT
 * @return
 */
uint8_t BulkOnly::SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir) {
        // promote buf_size to 32bits.
        CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir);
        //SetCurLUN(cdb->LUN);
        return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
}

/**
 * Lock or Unlock the tray or door on device.
 * Caution: Some devices with buggy firmware will lock up.
 *
 * @param lun Logical Unit Number
 * @param lock 1 to lock, 0 to unlock
 * @return
 */
uint8_t BulkOnly::LockMedia(uint8_t lun, uint8_t lock) {
        Notify(PSTR("\r\nLockMedia\r\n"), 0x80);
        Notify(PSTR("---------\r\n"), 0x80);

        CDB6_t cdb = CDB6_t(SCSI_CMD_PREVENT_REMOVAL, lun, (uint8_t)0, lock);
        return SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_IN);
}

/**
 * Media control, for spindle motor and media tray or door.
 * This includes CDROM, TAPE and anything with a media loader.
 *
 * @param lun Logical Unit Number
 * @param ctl 0x00 Stop Motor, 0x01 Start Motor, 0x02 Eject Media, 0x03 Load Media
 * @return 0 on success
 */
uint8_t BulkOnly::MediaCTL(uint8_t lun, uint8_t ctl) {
        Notify(PSTR("\r\nMediaCTL\r\n"), 0x80);
        Notify(PSTR("-----------------\r\n"), 0x80);

        uint8_t rcode = MASS_ERR_UNIT_NOT_READY;
        if (bAddress) {
                CDB6_t cdb = CDB6_t(SCSI_CMD_START_STOP_UNIT, lun, ctl & 0x03, 0);
                rcode = SCSITransaction6(&cdb, (uint16_t)0, NULL, (uint8_t)MASS_CMD_DIR_OUT);
        } else {
                SetCurLUN(lun);
        }
        return rcode;
}

/**
 * Read data from media
 *
 * @param lun Logical Unit Number
 * @param addr LBA address on media to read
 * @param bsize size of a block (we should probably use the cached size)
 * @param blocks how many blocks to read
 * @param buf memory that is able to hold the requested data
 * @return 0 on success
 */
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
        if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
        Notify(PSTR("\r\nRead LUN:\t"), 0x80);
        D_PrintHex<uint8_t > (lun, 0x90);
        Notify(PSTR("\r\nLBA:\t\t"), 0x90);
        D_PrintHex<uint32_t > (addr, 0x90);
        Notify(PSTR("\r\nblocks:\t\t"), 0x90);
        D_PrintHex<uint8_t > (blocks, 0x90);
        Notify(PSTR("\r\nblock size:\t"), 0x90);
        D_PrintHex<uint16_t > (bsize, 0x90);
        Notify(PSTR("\r\n---------\r\n"), 0x80);
        CDB10_t cdb = CDB10_t(SCSI_CMD_READ_10, lun, blocks, addr);

again:
        uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN);

        if (er == MASS_ERR_STALL) {
                MediaCTL(lun, 1);
                delay(150);
                if (!TestUnitReady(lun)) goto again;
        }
        return er;
}

/**
 * Write data to media
 *
 * @param lun Logical Unit Number
 * @param addr LBA address on media to write
 * @param bsize size of a block (we should probably use the cached size)
 * @param blocks how many blocks to write
 * @param buf memory that contains the data to write
 * @return 0 on success
 */
uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) {
        if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
        if (!WriteOk[lun]) return MASS_ERR_WRITE_PROTECTED;
        Notify(PSTR("\r\nWrite LUN:\t"), 0x80);
        D_PrintHex<uint8_t > (lun, 0x90);
        Notify(PSTR("\r\nLBA:\t\t"), 0x90);
        D_PrintHex<uint32_t > (addr, 0x90);
        Notify(PSTR("\r\nblocks:\t\t"), 0x90);
        D_PrintHex<uint8_t > (blocks, 0x90);
        Notify(PSTR("\r\nblock size:\t"), 0x90);
        D_PrintHex<uint16_t > (bsize, 0x90);
        Notify(PSTR("\r\n---------\r\n"), 0x80);
        CDB10_t cdb = CDB10_t(SCSI_CMD_WRITE_10, lun, blocks, addr);

again:
        uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT);

        if (er == MASS_ERR_WRITE_STALL) {
                MediaCTL(lun, 1);
                delay(150);
                if (!TestUnitReady(lun)) goto again;
        }
        return er;
}

// End of user functions, the remaining code below is driver internals.
// Only developer serviceable parts below!

////////////////////////////////////////////////////////////////////////////////

// Main driver code

////////////////////////////////////////////////////////////////////////////////

BulkOnly::BulkOnly(USB *p) :
pUsb(p),
bAddress(0),
bIface(0),
bNumEP(1),
qNextPollTime(0),
bPollEnable(false),
//dCBWTag(0),
bLastUsbError(0) {
        ClearAllEP();
        dCBWTag = 0;
        if (pUsb)
                pUsb->RegisterDeviceClass(this);
}

/**
 * USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET == success
 * We need to standardize either the rcode, or change the API to return values
 * so a signal that additional actions are required can be produced.
 * Some of these codes do exist already.
 *
 * TECHNICAL: We could do most of this code elsewhere, with the exception of checking the class instance.
 * Doing so would save some program memory when using multiple drivers.
 *
 * @param parent USB address of parent
 * @param port address of port on parent
 * @param lowspeed true if device is low speed
 * @return
 */
uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {

        const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);

        uint8_t buf[constBufSize];
        uint8_t rcode;
        UsbDevice *p = NULL;
        EpInfo *oldep_ptr = NULL;
        USBTRACE("MS ConfigureDevice\r\n");
        ClearAllEP();
        AddressPool &addrPool = pUsb->GetAddressPool();

        if (bAddress)
                return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;

        // <TECHNICAL>
        // Get pointer to pseudo device with address 0 assigned
        p = addrPool.GetUsbDevicePtr(0);
        if (!p) {
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
        }

        if (!p->epinfo) {
                USBTRACE("epinfo\r\n");
                return USB_ERROR_EPINFO_IS_NULL;
        }

        // Save old pointer to EP_RECORD of address 0
        oldep_ptr = p->epinfo;

        // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
        p->epinfo = epInfo;

        p->lowspeed = lowspeed;
        // Get device descriptor
        rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf);

        // Restore p->epinfo
        p->epinfo = oldep_ptr;

        if (rcode) {
                goto FailGetDevDescr;
        }
        // Allocate new address according to device class
        bAddress = addrPool.AllocAddress(parent, false, port);

        if (!bAddress)
                return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;

        // Extract Max Packet Size from the device descriptor
        epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
        // Steal and abuse from epInfo structure to save on memory.
        epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
        // </TECHNICAL>
        return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;

FailGetDevDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetDevDescr(rcode);
#endif
        rcode = USB_ERROR_FailGetDevDescr;

Fail:
        Release();
        return rcode;
};

/**
 *
 * @param parent (not used)
 * @param port (not used)
 * @param lowspeed true if device is low speed
 * @return 0 for success
 */
uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
        uint8_t rcode;
        uint8_t num_of_conf = epInfo[1].epAddr; // number of configurations
        epInfo[1].epAddr = 0;
        USBTRACE("MS Init\r\n");

        AddressPool &addrPool = pUsb->GetAddressPool();
        UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress);

        if (!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        // Assign new address to the device
        delay(2000);
        rcode = pUsb->setAddr(0, 0, bAddress);

        if (rcode) {
                p->lowspeed = false;
                addrPool.FreeAddress(bAddress);
                bAddress = 0;
                USBTRACE2("setAddr:", rcode);
                return rcode;
        }

        USBTRACE2("Addr:", bAddress);

        p->lowspeed = false;

        p = addrPool.GetUsbDevicePtr(bAddress);

        if (!p)
                return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;

        p->lowspeed = lowspeed;

        // Assign epInfo to epinfo pointer
        rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

        if (rcode)
                goto FailSetDevTblEntry;

        USBTRACE2("NC:", num_of_conf);

        for (uint8_t i = 0; i < num_of_conf; i++) {
                ConfigDescParser< USB_CLASS_MASS_STORAGE,
                        MASS_SUBCLASS_SCSI,
                        MASS_PROTO_BBB,
                        CP_MASK_COMPARE_CLASS |
                        CP_MASK_COMPARE_SUBCLASS |
                        CP_MASK_COMPARE_PROTOCOL > BulkOnlyParser(this);

                rcode = pUsb->getConfDescr(bAddress, 0, i, &BulkOnlyParser);

                if (rcode)
                        goto FailGetConfDescr;

                if (bNumEP > 1)
                        break;
        }

        if (bNumEP < 3)
                return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;

        // Assign epInfo to epinfo pointer
        pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);

        USBTRACE2("Conf:", bConfNum);

        // Set Configuration Value
        rcode = pUsb->setConf(bAddress, 0, bConfNum);

        if (rcode)
                goto FailSetConfDescr;

        //Linux does a 1sec delay after this.
        delay(1000);

        rcode = GetMaxLUN(&bMaxLUN);
        if (rcode)
                goto FailGetMaxLUN;

        if (bMaxLUN >= MASS_MAX_SUPPORTED_LUN) bMaxLUN = MASS_MAX_SUPPORTED_LUN - 1;
        ErrorMessage<uint8_t > (PSTR("MaxLUN"), bMaxLUN);

        delay(1000); // Delay a bit for slow firmware.

        for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
                InquiryResponse response;
                rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
                if (rcode) {
                        ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
                } else {
#if 0
                        printf("LUN %i `", lun);
                        uint8_t *buf = response.VendorID;
                        for (int i = 0; i < 28; i++) printf("%c", buf[i]);
                        printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier);
                        printf("Device type %2.2X ", response.DeviceType);
                        printf("RMB %1.1X ", response.Removable);
                        printf("SSCS %1.1X ", response.SCCS);
                        uint8_t sv = response.Version;
                        printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
                        switch (sv) {
                                case 0:
                                        printf("No specific");
                                        break;
                                case 1:
                                        printf("ANSI X3.131-1986 (ANSI 1)");
                                        break;
                                case 2:
                                        printf("ANSI X3.131-1994 (ANSI 2)");
                                        break;
                                case 3:
                                        printf("ANSI INCITS 301-1997 (SPC)");
                                        break;
                                case 4:
                                        printf("ANSI INCITS 351-2001 (SPC-2)");
                                        break;
                                case 5:
                                        printf("ANSI INCITS 408-2005 (SPC-4)");
                                        break;
                                case 6:
                                        printf("T10/1731-D (SPC-4)");
                                        break;
                                default:
                                        printf("unknown");
                        }
                        printf(" standards.\r\n");
#endif
                        uint8_t tries = 0xf0;
                        while (rcode = TestUnitReady(lun)) {
                                if (rcode == 0x08) break; // break on no media, this is OK to do.
                                // try to lock media and spin up
                                if (tries < 14) {
                                        LockMedia(lun, 1);
                                        MediaCTL(lun, 1); // I actually have a USB stick that needs this!
                                } else delay(2 * (tries + 1));
                                tries++;
                                if (!tries) break;
                        }
                        if (!rcode) {
                                delay(1000);
                                LUNOk[lun] = CheckLUN(lun);
                                if (!LUNOk[lun]) LUNOk[lun] = CheckLUN(lun);
                        }
                }
        }

        CheckMedia();

        rcode = OnInit();

        if (rcode)
                goto FailOnInit;

#ifdef DEBUG_USB_HOST
        USBTRACE("MS configured\r\n\r\n");
#endif

        bPollEnable = true;

        //USBTRACE("Poll enabled\r\n");
        return 0;

FailSetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailSetConfDescr();
        goto Fail;
#endif

FailOnInit:
#ifdef DEBUG_USB_HOST
        USBTRACE("OnInit:");
        goto Fail;
#endif

FailGetMaxLUN:
#ifdef DEBUG_USB_HOST
        USBTRACE("GetMaxLUN:");
        goto Fail;
#endif

FailInvalidSectorSize:
#ifdef DEBUG_USB_HOST
        USBTRACE("Sector Size is NOT VALID: ");
        goto Fail;
#endif

FailSetDevTblEntry:
#ifdef DEBUG_USB_HOST
        NotifyFailSetDevTblEntry();
        goto Fail;
#endif

FailGetConfDescr:
#ifdef DEBUG_USB_HOST
        NotifyFailGetConfDescr();
#endif

Fail:
#ifdef DEBUG_USB_HOST
        NotifyFail(rcode);
#endif
        Release();
        return rcode;
}

/**
 * For driver use only.
 *
 * @param conf
 * @param iface
 * @param alt
 * @param proto
 * @param pep
 */
void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR * pep) {
        ErrorMessage<uint8_t > (PSTR("Conf.Val"), conf);
        ErrorMessage<uint8_t > (PSTR("Iface Num"), iface);
        ErrorMessage<uint8_t > (PSTR("Alt.Set"), alt);

        bConfNum = conf;

        uint8_t index;

        if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
                index = epInterruptInIndex;
        else
                if ((pep->bmAttributes & 0x02) == 2)
                index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
        else
                return;

        // Fill in the endpoint info structure
        epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
        epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
        epInfo[index].epAttribs = 0;

        bNumEP++;

        PrintEndpointDescriptor(pep);
}

/**
 * For driver use only.
 *
 * @return
 */
uint8_t BulkOnly::Release() {
        ClearAllEP();
        pUsb->GetAddressPool().FreeAddress(bAddress);
        return 0;
}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @return true if LUN is ready for use.
 */
boolean BulkOnly::CheckLUN(uint8_t lun) {
        uint8_t rcode;
        Capacity capacity;
        for (uint8_t i = 0; i < 8; i++) capacity.data[i] = 0;

        rcode = ReadCapacity10(lun, (uint8_t*)capacity.data);
        if (rcode) {
                //printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
                return false;
        }
        ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
        for (uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++)
                D_PrintHex<uint8_t > (capacity.data[i], 0x80);
        Notify(PSTR("\r\n\r\n"), 0x80);
        // Only 512/1024/2048/4096 are valid values!
        uint32_t c = BMAKE32(capacity.data[4], capacity.data[5], capacity.data[6], capacity.data[7]);
        if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
                return false;
        }
        // Store capacity information.
        CurrentSectorSize[lun] = (uint16_t)(c); // & 0xFFFF);

        CurrentCapacity[lun] = BMAKE32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1;
        if (CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) {
                // Buggy firmware will report 0xffffffff or 0 for no media
                if (CurrentCapacity[lun])
                        ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
                return false;
        }
        delay(20);
        Page3F(lun);
        if (!TestUnitReady(lun)) return true;
        return false;
}

/**
 * For driver use only.
 *
 * Scan for media change on all LUNs
 */
void BulkOnly::CheckMedia() {
        for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
                if (TestUnitReady(lun)) {
                        LUNOk[lun] = false;
                        continue;
                }
                if (!LUNOk[lun])
                        LUNOk[lun] = CheckLUN(lun);
        }
#if 0
        printf("}}}}}}}}}}}}}}}}STATUS ");
        for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
                if (LUNOk[lun])
                        printf("#");
                else printf(".");
        }
        printf("\r\n");
#endif
        qNextPollTime = millis() + 2000;
}

/**
 * For driver use only.
 *
 * @return
 */
uint8_t BulkOnly::Poll() {
        //uint8_t rcode = 0;

        if (!bPollEnable)
                return 0;

        if (qNextPollTime <= millis()) {
                CheckMedia();
        }
        //rcode = 0;

        return 0;
}

////////////////////////////////////////////////////////////////////////////////

// SCSI code

////////////////////////////////////////////////////////////////////////////////

/**
 * For driver use only.
 *
 * @param plun
 * @return
 */
uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
        uint8_t ret = pUsb->ctrlReq(bAddress, 0, bmREQ_MASSIN, MASS_REQ_GET_MAX_LUN, 0, 0, bIface, 1, 1, plun, NULL);

        if (ret == hrSTALL)
                *plun = 0;

        return 0;
}

/**
 * For driver use only. Used during Driver Init
 *
 * @param lun Logical Unit Number
 * @param bsize
 * @param buf
 * @return
 */
uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
        Notify(PSTR("\r\nInquiry\r\n"), 0x80);
        Notify(PSTR("---------\r\n"), 0x80);

        CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0LU, (uint8_t)bsize, 0);
        uint8_t rc = SCSITransaction6(&cdb, bsize, buf, (uint8_t)MASS_CMD_DIR_IN);

        return rc;
}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @return
 */
uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
        //SetCurLUN(lun);
        if (!bAddress)
                return MASS_ERR_UNIT_NOT_READY;

        Notify(PSTR("\r\nTestUnitReady\r\n"), 0x80);
        Notify(PSTR("-----------------\r\n"), 0x80);

        CDB6_t cdb = CDB6_t(SCSI_CMD_TEST_UNIT_READY, lun, (uint8_t)0, 0);
        return SCSITransaction6(&cdb, 0, NULL, (uint8_t)MASS_CMD_DIR_IN);

}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @param pc
 * @param page
 * @param subpage
 * @param len
 * @param pbuf
 * @return
 */
uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
        Notify(PSTR("\r\rModeSense\r\n"), 0x80);
        Notify(PSTR("------------\r\n"), 0x80);

        CDB6_t cdb = CDB6_t(SCSI_CMD_TEST_UNIT_READY, lun, (uint32_t)((((pc << 6) | page) << 8) | subpage), len, 0);
        return SCSITransaction6(&cdb, len, pbuf, (uint8_t)MASS_CMD_DIR_IN);
}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @param bsize
 * @param buf
 * @return
 */
uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
        Notify(PSTR("\r\nReadCapacity\r\n"), 0x80);
        Notify(PSTR("---------------\r\n"), 0x80);

        CDB10_t cdb = CDB10_t(SCSI_CMD_READ_CAPACITY_10, lun);
        return SCSITransaction10(&cdb, 8, buf, (uint8_t)MASS_CMD_DIR_IN);
}

/**
 * For driver use only.
 *
 * Page 3F contains write protect status.
 *
 * @param lun Logical Unit Number to test.
 * @return Write protect switch status.
 */
uint8_t BulkOnly::Page3F(uint8_t lun) {
        uint8_t buf[192];
        for (int i = 0; i < 192; i++) {
                buf[i] = 0x00;
        }
        WriteOk[lun] = true;
        uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
        if (!rc) {
                WriteOk[lun] = ((buf[2] & 0x80) == 0);
                Notify(PSTR("Mode Sense: "), 0x80);
                for (int i = 0; i < 4; i++) {
                        D_PrintHex<uint8_t > (buf[i], 0x80);
                        Notify(PSTR(" "), 0x80);
                }
                Notify(PSTR("\r\n"), 0x80);
        }
        return rc;
}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @param size
 * @param buf
 * @return
 */
uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
        Notify(PSTR("\r\nRequestSense\r\n"), 0x80);
        Notify(PSTR("----------------\r\n"), 0x80);

        CDB6_t cdb = CDB6_t(SCSI_CMD_REQUEST_SENSE, lun, 0LU, (uint8_t)size, 0);
        CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)size, &cdb, (uint8_t)MASS_CMD_DIR_IN);
        //SetCurLUN(lun);
        return Transaction(&cbw, size, buf);
}

////////////////////////////////////////////////////////////////////////////////

// USB code

////////////////////////////////////////////////////////////////////////////////

/**
 * For driver use only.
 *
 * @param index
 * @return
 */
uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
        if (index == 0)
                return 0;

        uint8_t ret = 0;

        while (ret = (pUsb->ctrlReq(bAddress, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT,
                USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr), 0, 0, NULL, NULL))
                == 0x01) delay(6);

        if (ret) {
                ErrorMessage<uint8_t > (PSTR("ClearEpHalt"), ret);
                ErrorMessage<uint8_t > (PSTR("EP"), ((index == epDataInIndex) ? (0x80 | epInfo[index].epAddr) : epInfo[index].epAddr));
                return ret;
        }
        epInfo[index].bmSndToggle = 0;
        epInfo[index].bmRcvToggle = 0;
        // epAttribs = 0;
        return 0;
}

/**
 * For driver use only.
 *
 */
void BulkOnly::Reset() {
        while (pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
}

/**
 * For driver use only.
 *
 * @return 0 if successful
 */
uint8_t BulkOnly::ResetRecovery() {
        Notify(PSTR("\r\nResetRecovery\r\n"), 0x80);
        Notify(PSTR("-----------------\r\n"), 0x80);

        delay(6);
        Reset();
        delay(6);
        ClearEpHalt(epDataInIndex);
        delay(6);
        bLastUsbError = ClearEpHalt(epDataOutIndex);
        delay(6);
        return bLastUsbError;
}

/**
 * For driver use only.
 *
 * Clear all EP data and clear all LUN status
 */
void BulkOnly::ClearAllEP() {
        for (uint8_t i = 0; i < MASS_MAX_ENDPOINTS; i++) {
                epInfo[i].epAddr = 0;
                epInfo[i].maxPktSize = (i) ? 0 : 8;
                epInfo[i].epAttribs = 0;

                epInfo[i].bmNakPower = USB_NAK_DEFAULT;
        }

        for (uint8_t i = 0; i < MASS_MAX_SUPPORTED_LUN; i++) {
                LUNOk[i] = false;
                WriteOk[i] = false;
                CurrentCapacity[i] = 0lu;
                CurrentSectorSize[i] = 0;
        }

        bIface = 0;
        bNumEP = 1;
        bAddress = 0;
        qNextPollTime = 0;
        bPollEnable = false;
        bLastUsbError = 0;
        bMaxLUN = 0;
        bTheLUN = 0;
}

/**
 * For driver use only.
 *
 * @param pcsw
 * @param pcbw
 * @return
 */
bool BulkOnly::IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw) {
        if (pcsw->dCSWSignature != MASS_CSW_SIGNATURE) {
                Notify(PSTR("CSW:Sig error\r\n"), 0x80);
                return false;
        }
        if (pcsw->dCSWTag != pcbw->dCBWTag) {
                Notify(PSTR("CSW:Wrong tag\r\n"), 0x80);
                return false;
        }
        return true;
}

/**
 * For driver use only.
 *
 * @param error
 * @param index
 * @return
 */
uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
        uint8_t count = 3;

        bLastUsbError = error;
        //if (error)
        //ClearEpHalt(index);
        while (error && count) {
                if (error != hrSUCCESS) {
                        ErrorMessage<uint8_t > (PSTR("USB Error"), error);
                        ErrorMessage<uint8_t > (PSTR("Index"), index);
                }
                switch (error) {
                                // case hrWRONGPID:
                        case hrSUCCESS:
                                return MASS_ERR_SUCCESS;
                        case hrBUSY:
                                // SIE is busy, just hang out and try again.
                                return MASS_ERR_UNIT_BUSY;
                        case hrTIMEOUT:
                        case hrJERR: return MASS_ERR_DEVICE_DISCONNECTED;
                        case hrSTALL:
                                if (index == 0)
                                        return MASS_ERR_STALL;
                                ClearEpHalt(index);
                                if (index != epDataInIndex)
                                        return MASS_ERR_WRITE_STALL;
                                return MASS_ERR_STALL;

                        case hrNAK:
                                if (index == 0)
                                        return MASS_ERR_UNIT_BUSY;
                                return MASS_ERR_UNIT_BUSY;

                        case hrTOGERR:
                                // Handle a very super rare corner case, where toggles become de-synched.
                                // I have only ran into one device that has this firmware bug, and this is
                                // the only clean way to get back into sync with the buggy device firmware.
                                //   --AJK
                                if (bAddress && bConfNum) {
                                        error = pUsb->setConf(bAddress, 0, bConfNum);

                                        if (error)
                                                break;
                                }
                                return MASS_ERR_SUCCESS;
                        default:
                                ErrorMessage<uint8_t > (PSTR("\r\nUSB"), error);
                                return MASS_ERR_GENERAL_USB_ERROR;
                }
                count--;
        } // while

        return ((error && !count) ? MASS_ERR_GENERAL_USB_ERROR : MASS_ERR_SUCCESS);
}

#if MS_WANT_PARSER

uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf) {
        return Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf, 0);
}
#endif

/**
 * For driver use only.
 *
 * @param pcbw
 * @param buf_size
 * @param buf
 * @param flags
 * @return
 */
uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf
#if MS_WANT_PARSER
        , uint8_t flags
#endif
        ) {

#if MS_WANT_PARSER
        uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength;
        printf("Transfersize %i\r\n", bytes);
        delay(1000);

        boolean callback = (flags & MASS_TRANS_FLG_CALLBACK) == MASS_TRANS_FLG_CALLBACK;
#else
        uint16_t bytes = buf_size;
#endif
        boolean write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN;
        uint8_t ret = 0;
        uint8_t usberr;
        CommandStatusWrapper csw; // up here, we allocate ahead to save cpu cycles.
        SetCurLUN(pcbw->bmCBWLUN);
        ErrorMessage<uint32_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);

        while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1);

        ret = HandleUsbError(usberr, epDataOutIndex);
        //ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex);
        if (ret) {
                ErrorMessage<uint8_t > (PSTR("============================ CBW"), ret);
        } else {
                if (bytes) {
                        if (!write) {
#if MS_WANT_PARSER
                                if (callback) {
                                        uint8_t rbuf[bytes];
                                        while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, rbuf)) == hrBUSY) delay(1);
                                        if (usberr == hrSUCCESS) ((USBReadParser*)buf)->Parse(bytes, rbuf, 0);
                                } else {
#endif
                                        while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
#if MS_WANT_PARSER

                                }
#endif
                                ret = HandleUsbError(usberr, epDataInIndex);
                        } else {
                                while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes, (uint8_t*)buf)) == hrBUSY) delay(1);
                                ret = HandleUsbError(usberr, epDataOutIndex);
                        }
                        if (ret) {
                                ErrorMessage<uint8_t > (PSTR("============================ DAT"), ret);
                        }
                }
        }

        {
                bytes = sizeof (CommandStatusWrapper);
                int tries = 2;
                while (tries--) {
                        while ((usberr = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &bytes, (uint8_t*) & csw)) == hrBUSY) delay(1);
                        if (!usberr) break;
                        ClearEpHalt(epDataInIndex);
                        if (tries) ResetRecovery();
                }
                if (!ret) {
                        Notify(PSTR("CBW:\t\tOK\r\n"), 0x80);
                        Notify(PSTR("Data Stage:\tOK\r\n"), 0x80);
                } else {
                        // Throw away csw, IT IS NOT OF ANY USE.
                        ResetRecovery();
                        return ret;
                }
                ret = HandleUsbError(usberr, epDataInIndex);
                if (ret) {
                        ErrorMessage<uint8_t > (PSTR("============================ CSW"), ret);
                }
                if (usberr == hrSUCCESS) {
                        if (IsValidCSW(&csw, pcbw)) {
                                //ErrorMessage<uint32_t > (PSTR("CSW.dCBWTag"), csw.dCSWTag);
                                //ErrorMessage<uint8_t > (PSTR("bCSWStatus"), csw.bCSWStatus);
                                //ErrorMessage<uint32_t > (PSTR("dCSWDataResidue"), csw.dCSWDataResidue);
                                Notify(PSTR("CSW:\t\tOK\r\n\r\n"), 0x80);
                                return csw.bCSWStatus;
                        } else {
                                // NOTE! Sometimes this is caused by the reported residue being wrong.
                                // Get a different device. It isn't compliant, and should have never passed Q&A.
                                // I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter.
                                // Other devices that exhibit this behavior exist in the wild too.
                                // Be sure to check quirks in the Linux source code before reporting a bug. --xxxajk
                                Notify(PSTR("Invalid CSW\r\n"), 0x80);
                                ResetRecovery();
                                //return MASS_ERR_SUCCESS;
                                return MASS_ERR_INVALID_CSW;
                        }
                }
        }
        return ret;
}

/**
 * For driver use only.
 *
 * @param lun Logical Unit Number
 * @return
 */
uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
        if (lun > bMaxLUN)
                return MASS_ERR_INVALID_LUN;
        bTheLUN = lun;
        return MASS_ERR_SUCCESS;
};

/**
 * For driver use only.
 *
 * @param status
 * @return
 */
uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
        uint8_t ret = 0;

        switch (status) {
                case 0: return MASS_ERR_SUCCESS;

                case 2:
                        ErrorMessage<uint8_t > (PSTR("Phase Error"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        ResetRecovery();
                        return MASS_ERR_GENERAL_SCSI_ERROR;

                case 1:
                        ErrorMessage<uint8_t > (PSTR("SCSI Error"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        RequestSenseResponce rsp;

                        ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);

                        if (ret) {
                                return MASS_ERR_GENERAL_SCSI_ERROR;
                        }
                        ErrorMessage<uint8_t > (PSTR("Response Code"), rsp.bResponseCode);
                        if (rsp.bResponseCode & 0x80) {
                                Notify(PSTR("Information field: "), 0x80);
                                for (int i = 0; i < 4; i++) {
                                        D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
                                        Notify(PSTR(" "), 0x80);
                                }
                                Notify(PSTR("\r\n"), 0x80);
                        }
                        ErrorMessage<uint8_t > (PSTR("Sense Key"), rsp.bmSenseKey);
                        ErrorMessage<uint8_t > (PSTR("Add Sense Code"), rsp.bAdditionalSenseCode);
                        ErrorMessage<uint8_t > (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier);
                        // warning, this is not testing ASQ, only SK and ASC.
                        switch (rsp.bmSenseKey) {
                                case SCSI_S_UNIT_ATTENTION:
                                        switch (rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_MEDIA_CHANGED:
                                                        return MASS_ERR_MEDIA_CHANGED;
                                                default:
                                                        return MASS_ERR_UNIT_NOT_READY;
                                        }
                                case SCSI_S_NOT_READY:
                                        switch (rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_MEDIUM_NOT_PRESENT:
                                                        return MASS_ERR_NO_MEDIA;
                                                default:
                                                        return MASS_ERR_UNIT_NOT_READY;
                                        }
                                case SCSI_S_ILLEGAL_REQUEST:
                                        switch (rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_LBA_OUT_OF_RANGE:
                                                        return MASS_ERR_BAD_LBA;
                                                default:
                                                        return MASS_ERR_CMD_NOT_SUPPORTED;
                                        }
                                default:
                                        return MASS_ERR_GENERAL_SCSI_ERROR;
                        }

                        // case 4: return MASS_ERR_UNIT_BUSY; // Busy means retry later.
                        //    case 0x05/0x14: we stalled out
                        //    case 0x15/0x16: we naked out.
                default:
                        ErrorMessage<uint8_t > (PSTR("Gen SCSI Err"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        return status;
        } // switch
}

////////////////////////////////////////////////////////////////////////////////

// Debugging code

////////////////////////////////////////////////////////////////////////////////

/**
 *
 * @param ep_ptr
 */
void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
        Notify(PSTR("Endpoint descriptor:"), 0x80);
        Notify(PSTR("\r\nLength:\t\t"), 0x80);
        D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
        Notify(PSTR("\r\nType:\t\t"), 0x80);
        D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80);
        Notify(PSTR("\r\nAddress:\t"), 0x80);
        D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80);
        Notify(PSTR("\r\nAttributes:\t"), 0x80);
        D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80);
        Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
        D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80);
        Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
        D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80);
        Notify(PSTR("\r\n"), 0x80);
}

////////////////////////////////////////////////////////////////////////////////

// misc/to kill/to-do

////////////////////////////////////////////////////////////////////////////////

/* We won't be needing this... */
uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser * prs) {
#if MS_WANT_PARSER
        if (!LUNOk[lun]) return MASS_ERR_NO_MEDIA;
        Notify(PSTR("\r\nRead (With parser)\r\n"), 0x80);
        Notify(PSTR("---------\r\n"), 0x80);

        CommandBlockWrapper cbw = CommandBlockWrapper();

        cbw.dCBWSignature = MASS_CBW_SIGNATURE;
        cbw.dCBWTag = ++dCBWTag;
        cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
        cbw.bmCBWFlags = MASS_CMD_DIR_IN,
                cbw.bmCBWLUN = lun;
        cbw.bmCBWCBLength = 10;

        cbw.CBWCB[0] = SCSI_CMD_READ_10;
        cbw.CBWCB[8] = blocks;
        cbw.CBWCB[2] = ((addr >> 24) & 0xff);
        cbw.CBWCB[3] = ((addr >> 16) & 0xff);
        cbw.CBWCB[4] = ((addr >> 8) & 0xff);
        cbw.CBWCB[5] = (addr & 0xff);

        return HandleSCSIError(Transaction(&cbw, bsize, prs, 1));
#else
        return MASS_ERR_NOT_IMPLEMENTED;
#endif
}


text:
package net.fortuna.ical4j.model.property;

import net.fortuna.ical4j.model.*;
import net.fortuna.ical4j.util.Strings;
import net.fortuna.ical4j.util.Uris;
import net.fortuna.ical4j.validate.ParameterValidator;
import net.fortuna.ical4j.validate.ValidationException;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.Arrays;

/**
 * $Id$
 *

 * Created: [Apr 6, 2004]
 *

 * Defines an ATTENDEE iCalendar component property.
 *
 * @author benf
 */
public class Attendee extends Property {

    private static final long serialVersionUID = 8430929418723298803L;

    private URI calAddress;

    /**
     * Default constructor.
     */
    public Attendee() {
        super(ATTENDEE, new Factory());
    }

    /**
     * @param aValue a value string for this component
     * @throws URISyntaxException where the specified value string is not a valid uri
     */
    public Attendee(final String aValue) throws URISyntaxException {
        super(ATTENDEE, new Factory());
        setValue(aValue);
    }

    /**
     * @param aList  a list of parameters for this component
     * @param aValue a value string for this component
     * @throws URISyntaxException where the specified value string is not a valid uri
     */
    public Attendee(final ParameterList aList, final String aValue)
            throws URISyntaxException {
        super(ATTENDEE, aList, new Factory());
        setValue(aValue);
    }

    /**
     * @param aUri a URI
     */
    public Attendee(final URI aUri) {
        super(ATTENDEE, new Factory());
        calAddress = aUri;
    }

    /**
     * @param aList a list of parameters for this component
     * @param aUri  a URI
     */
    public Attendee(final ParameterList aList, final URI aUri) {
        super(ATTENDEE, aList, new Factory());
        calAddress = aUri;
    }

    /**
     * {@inheritDoc}
     */
    public final void setValue(final String aValue) throws URISyntaxException {
        calAddress = Uris.create(aValue);
    }

    /**
     * {@inheritDoc}
     */
    public final void validate() throws ValidationException {

        /*
         * ; the following are optional, ; but MUST NOT occur more than once (";" cutypeparam) / (";"memberparam) / (";"
         * roleparam) / (";" partstatparam) / (";" rsvpparam) / (";" deltoparam) / (";" delfromparam) / (";"
         * sentbyparam) / (";"cnparam) / (";" dirparam) / (";" languageparam) /
         */
        Arrays.asList(Parameter.CUTYPE, Parameter.MEMBER, Parameter.ROLE, Parameter.PARTSTAT,
                Parameter.RSVP, Parameter.DELEGATED_TO, Parameter.DELEGATED_FROM, Parameter.SENT_BY, Parameter.CN,
                Parameter.DIR, Parameter.LANGUAGE).forEach(parameter -> ParameterValidator.assertOneOrLess(parameter, getParameters()));

        /* scheduleagent and schedulestatus added for CalDAV scheduling
         */
        ParameterValidator.assertOneOrLess(Parameter.SCHEDULE_AGENT,
                getParameters());
        ParameterValidator.assertOneOrLess(Parameter.SCHEDULE_STATUS,
                getParameters());
        /*
         * ; the following is optional, ; and MAY occur more than once (";" xparam)
         */
    }

    /**
     * @return Returns the calAddress.
     */
    public final URI getCalAddress() {
        return calAddress;
    }

    /**
     * {@inheritDoc}
     */
    public final String getValue() {
        return Uris.decode(Strings.valueOf(getCalAddress()));
    }

    /**
     * @param calAddress The calAddress to set.
     */
    public final void setCalAddress(final URI calAddress) {
        this.calAddress = calAddress;
    }

    /**
     * {@inheritDoc}
     */
    public final Property copy() {
        // URI are immutable
        return new Attendee(new ParameterList(getParameters(), false), calAddress);
    }

    public static class Factory extends Content.Factory implements PropertyFactory {
        private static final long serialVersionUID = 1L;

        public Factory() {
            super(ATTENDEE);
        }

        public Property createProperty(final ParameterList parameters, final String value)
                throws IOException, URISyntaxException, ParseException {
            return new Attendee(parameters, value);
        }

        public Property createProperty() {
            return new Attendee();
        }
    }

}


text:
package com.bitdubai.fermat_core.layer.p2p_communication;

import com.bitdubai.fermat_api.Plugin;
import com.bitdubai.fermat_api.layer.all_definition.enums.NetworkServices;
import com.bitdubai.fermat_p2p_api.layer.p2p_communication.*;

import java.util.UUID;

/**
 * Created by ciencias on 2/12/15.
 */

/**
 * This objects wraps the user to user online connection provided by the plugin. The purpose of doing this is to handle
 * the disconnection of the remote user to the channel the plugin is working on.
 *
 * In case of detecting such disconnection this object will try to reconnect through the same channel or other alternatives
 * available.
 */

public class LayerServiceToServiceOnlineConnection implements ServiceToServiceOnlineConnection{

    Plugin cloudPlugin;
    Plugin p2pPlugin;

    ServiceToServiceOnlineConnection serviceToServiceOnlineConnection;

    NetworkServices networkService;
    UUID remoteNetworkService;

    public LayerServiceToServiceOnlineConnection(NetworkServices networkService, UUID remoteNetworkService) {

        this.networkService = networkService;
        this.remoteNetworkService = remoteNetworkService;

    }

    public void setCloudPlugin (Plugin cloudPlugin){
        this.cloudPlugin = cloudPlugin;
    }

    public void setP2pPlugin (Plugin p2pPlugin){
        this.p2pPlugin = cloudPlugin;
    }

    public void connect() throws CantConnectToRemoteServiceException {

        try
        {
            connectByAnyChannel();
        }
        catch (CantConnectToRemoteServiceException cantConnectToRemoteServiceException)
        {
            System.err.println("CantConnectToRemoteServiceException: " + cantConnectToRemoteServiceException.getMessage());

            throw cantConnectToRemoteServiceException;
        }

    }

    @Override
    public void reConnect() throws CantConnectToRemoteServiceException {

        this.serviceToServiceOnlineConnection.disconnect();

        try
        {
            connectByAnyChannel();
        }
        catch (CantConnectToRemoteServiceException cantConnectToRemoteServiceException)
        {
            System.err.println("CantConnectToRemoteServiceException: " + cantConnectToRemoteServiceException.getMessage());

            throw cantConnectToRemoteServiceException;
        }
    }

    @Override
    public void disconnect() {
        this.serviceToServiceOnlineConnection.disconnect();
    }

    @Override
    public ConnectionStatus getStatus() {
        return this.serviceToServiceOnlineConnection.getStatus();
    }

    @Override
    public void sendMessage(Message message) throws CantSendMessageException {
        this.serviceToServiceOnlineConnection.sendMessage(message);
        // Luis: TODO verificar la excepcion que puede devoler y si es un problema de desconexion actuar en concecuencia.
    }

    @Override
    public void clearMessage(Message message) {

    }

    @Override
    public int getUnreadMessagesCount() {
        return this.serviceToServiceOnlineConnection.getUnreadMessagesCount();
    }

    @Override
    public Message readNextMessage() {
        return this.serviceToServiceOnlineConnection.readNextMessage();
    }

    private void connectByAnyChannel() throws CantConnectToRemoteServiceException {

        /**
         * There are several ways to establish an online connection implemented by different plugins. It is also
         * possible to  try several of these ways until we find a connection to the desired service.
         */

        /**
         * As of today, there is only one way possible to connect to other services, and it is via the Cloud connection
         * channel.
         */

        OnlineChannel onlineChannel = ((CommunicationChannel) cloudPlugin).createOnlineChannel();

        try
        {
            this.serviceToServiceOnlineConnection =  onlineChannel.connectTo(this.networkService, this.remoteNetworkService);
        }
        catch (CantConnectToRemoteServiceException cantConnectToRemoteServiceException)
        {
            System.err.println("CantConnectToRemoteServiceException: " + cantConnectToRemoteServiceException.getMessage());

            /**
             * Since this is the only implementation of a communication channel if the connection cannot be established
             * then there is no other option but to throw the exception again.
             */
            throw cantConnectToRemoteServiceException;
        }
    }

}


text:
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding model 'Metonymy'
        db.create_table('dictionary_metonymy', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('name', self.gf('django.db.models.fields.CharField')(max_length=45, db_column='name')),
        ))
        db.send_create_signal(u'dictionary', ['Metonymy'])

        # Adding model 'Metaphor'
        db.create_table('dictionary_metaphor', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('name', self.gf('django.db.models.fields.CharField')(max_length=45, db_column='name')),
        ))
        db.send_create_signal(u'dictionary', ['Metaphor'])

        # Adding model 'SemanticField'
        db.create_table('dictionary_semantic_field', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('name', self.gf('django.db.models.fields.CharField')(max_length=45, db_column='name')),
        ))
        db.send_create_signal(u'dictionary', ['SemanticField'])

        # Deleting field 'Word.semantic_field'
        db.delete_column(u'dictionary_word', 'semantic_field')

        # Deleting field 'Word.metaphor'
        db.delete_column(u'dictionary_word', 'metaphor')

        # Deleting field 'Word.metonymy'
        db.delete_column(u'dictionary_word', 'metonymy')

        # Adding M2M table for field metaphor on 'Word'
        m2m_table_name = db.shorten_name('dictionary_word_metaphor')
        db.create_table(m2m_table_name, (
            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
            ('word', models.ForeignKey(orm[u'dictionary.word'], null=False)),
            ('metaphor', models.ForeignKey(orm[u'dictionary.metaphor'], null=False))
        ))
        db.create_unique(m2m_table_name, ['word_id', 'metaphor_id'])

    def backwards(self, orm):
        # Deleting model 'Metonymy'
        db.delete_table('dictionary_metonymy')

        # Deleting model 'Metaphor'
        db.delete_table('dictionary_metaphor')

        # Deleting model 'SemanticField'
        db.delete_table('dictionary_semantic_field')

        # Adding field 'Word.semantic_field'
        db.add_column(u'dictionary_word', 'semantic_field',
                      self.gf('django.db.models.fields.files.ImageField')(default='dictionary/semantic_field/default.png', max_length=100, db_column='semantic_field', blank=True),
                      keep_default=False)

        # Adding field 'Word.metaphor'
        db.add_column(u'dictionary_word', 'metaphor',
                      self.gf('django.db.models.fields.files.ImageField')(default='dictionary/metaphor/default.png', max_length=100, db_column='metaphor', blank=True),
                      keep_default=False)

        # Adding field 'Word.metonymy'
        db.add_column(u'dictionary_word', 'metonymy',
                      self.gf('django.db.models.fields.files.ImageField')(default='dictionary/metonymy/default.png', max_length=100, db_column='metonymy', blank=True),
                      keep_default=False)

        # Removing M2M table for field metaphor on 'Word'
        db.delete_table(db.shorten_name('dictionary_word_metaphor'))

    models = {
        u'dictionary.category': {
            'Meta': {'ordering': "['id']", 'object_name': 'Category'},
            'fcl': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['dictionary.FLC']", 'through': u"orm['dictionary.CategoryHasFLC']", 'symmetrical': 'False'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"})
        },
        u'dictionary.categoryhasflc': {
            'Meta': {'object_name': 'CategoryHasFLC', 'db_table': "'dictionary_category_has_flc'"},
            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.Category']", 'on_delete': 'models.PROTECT', 'db_column': "'category'"}),
            'flc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.FLC']", 'on_delete': 'models.PROTECT', 'db_column': "'flc'"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
        },
        u'dictionary.flc': {
            'Meta': {'ordering': "['id']", 'object_name': 'FLC'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"}),
            'slc': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['dictionary.SLC']", 'through': u"orm['dictionary.FLCHasSLC']", 'symmetrical': 'False'})
        },
        u'dictionary.flchasslc': {
            'Meta': {'object_name': 'FLCHasSLC', 'db_table': "'dictionary_flc_has_slc'"},
            'flc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.FLC']", 'on_delete': 'models.PROTECT', 'db_column': "'flc'"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'slc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.SLC']", 'on_delete': 'models.PROTECT', 'db_column': "'slc'"})
        },
        u'dictionary.metaphor': {
            'Meta': {'ordering': "['name']", 'object_name': 'Metaphor'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"})
        },
        u'dictionary.metonymy': {
            'Meta': {'ordering': "['name']", 'object_name': 'Metonymy'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"})
        },
        u'dictionary.semanticfield': {
            'Meta': {'ordering': "['name']", 'object_name': 'SemanticField', 'db_table': "'dictionary_semantic_field'"},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"})
        },
        u'dictionary.skill': {
            'Meta': {'ordering': "['id']", 'object_name': 'Skill'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': "'45'", 'db_column': "'name'"})
        },
        u'dictionary.slc': {
            'Meta': {'ordering': "['id']", 'object_name': 'SLC'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"}),
            'skill': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['dictionary.Skill']", 'through': u"orm['dictionary.SLCHasSkill']", 'symmetrical': 'False'})
        },
        u'dictionary.slchasskill': {
            'Meta': {'object_name': 'SLCHasSkill', 'db_table': "'dictionary_slc_has_skill'"},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'skill': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.Skill']", 'on_delete': 'models.PROTECT', 'db_column': "'skill'"}),
            'slc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.SLC']", 'on_delete': 'models.PROTECT', 'db_column': "'slc'"})
        },
        u'dictionary.word': {
            'Meta': {'ordering': "['order']", 'object_name': 'Word'},
            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.Category']", 'on_delete': 'models.PROTECT', 'db_column': "'category'"}),
            'description': ('django.db.models.fields.CharField', [], {'max_length': '140', 'db_column': "'description'", 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'image': ('django.db.models.fields.files.ImageField', [], {'default': "'dictionary/image/default.png'", 'max_length': '100', 'db_column': "'image'", 'blank': 'True'}),
            'map': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'map'", 'blank': 'True'}),
            'mark': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'mark'", 'blank': 'True'}),
            'metaphor': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['dictionary.Metaphor']", 'symmetrical': 'False'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'name'"}),
            'order': ('django.db.models.fields.PositiveIntegerField', [], {'db_column': "'order'"}),
            'skill': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['dictionary.Skill']", 'through': u"orm['dictionary.WordHasSkill']", 'symmetrical': 'False'})
        },
        u'dictionary.wordhasskill': {
            'Meta': {'object_name': 'WordHasSkill', 'db_table': "'dictionary_word_has_skill'"},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'skill': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.Skill']", 'on_delete': 'models.PROTECT', 'db_column': "'skill'"}),
            'value': ('django.db.models.fields.CharField', [], {'max_length': '45', 'db_column': "'value'"}),
            'word': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['dictionary.Word']", 'on_delete': 'models.PROTECT', 'db_column': "'word'"})
        }
    }

    complete_apps = ['dictionary']


text:
You'll need to do a pull-request similar to this [https://github.com/reactiveui/ReactiveUI/pull/1226](https://github.com/reactiveui/ReactiveUI/pull/1226)

![](/contribute/maintainers/release-failed-because-gitreleasemanager-could-not-find-the-milestone.png)

Change to a clean copy of `main`

```shell
git clean -fdx
git reset --hard
git checkout main
git pull
```

Create a new branch

```shell
git branch bump-release-version
```

If you want to bump the `BREAKING` create an empty commit in the branch with the following commit message

```
git commit --allow-empty -m "fix: the previous commit didn't bump with +semver: breaking"
```

If you want to bump the `FEATURE` create an empty commit in the branch with the following commit message

```
git commit --allow-empty -m "fix: the previous commit didn't bump with +semver: feature"
```

Push your branch

```shell
git push origin bump-release-version
```

Open a pull-request to `main` and once the release has been approved, you'll need to switch your merge mode to `Create a merge commit` aka `Merge pull request` by using the little arrow on the right hand side.

![](/contribute/maintainers/merge-commit-option.png)

Do not customize the merge commit message or more specifically, do not bump the semver in the merge commit message.

# Release failed because of labeling issue

Visit the issue, resolve the problem and then visit AppVeyor and click "Rebuild Commit". It is safe to do this multiple times because building `main` does not automatically release unless the commit has been tagged.

![](/contribute/maintainers/release-failed-because-of-labeling-issue.png)


text:
function Ball(r, p, v) {
    this.radius = r;
    this.point = p;
    this.vector = v;
    this.maxVec = 15;
    this.numSegment = Math.floor(r / 3 + 2);
    this.boundOffset = [];
    this.boundOffsetBuff = [];
    this.sidePoints = [];
    this.path = new Path({
        fillColor: {
            hue: 0,
            saturation: 0,
            brightness: 1,
            alpha: 0.5
        },
        blendMode: 'screen'
    });

    for (var i = 0; i < this.numSegment; i ++) {
        this.boundOffset.push(this.radius);
        this.boundOffsetBuff.push(this.radius);
        this.path.add(new Point());
        this.sidePoints.push(new Point({
            angle: 360 / this.numSegment * i,
            length: 1
        }));
    }
}

Ball.prototype = {
    iterate: function() {
        this.checkBorders();
        if (this.vector.length > this.maxVec)
            this.vector.length = this.maxVec;
        this.point += this.vector;
        this.updateShape();
    },

    checkBorders: function() {
        var size = view.size;
        if (this.point.x < -this.radius)
            this.point.x = size.width + this.radius;
        if (this.point.x > size.width + this.radius)
            this.point.x = -this.radius;
        if (this.point.y < -this.radius)
            this.point.y = size.height + this.radius;
        if (this.point.y > size.height + this.radius)
            this.point.y = -this.radius;
    },

    updateShape: function() {
        var segments = this.path.segments;
        for (var i = 0; i < this.numSegment; i ++)
            segments[i].point = this.getSidePoint(i);

        this.path.smooth();
        for (var i = 0; i < this.numSegment; i ++) {
            if (this.boundOffset[i] < this.radius / 4)
                this.boundOffset[i] = this.radius / 4;
            var next = (i + 1) % this.numSegment;
            var prev = (i > 0) ? i - 1 : this.numSegment - 1;
            var offset = this.boundOffset[i];
            offset += (this.radius - offset) / 15;
            offset += ((this.boundOffset[next] + this.boundOffset[prev]) / 2 - offset) / 3;
            this.boundOffsetBuff[i] = this.boundOffset[i] = offset;
        }
    },

    react: function(b) {
        return;
        var dist = this.point.getDistance(b.point);
        if (dist < this.radius + b.radius && dist != 0) {
            var overlap = this.radius + b.radius - dist;
            var direc = (this.point - b.point).normalize(overlap * 0.015);
            this.vector += direc;
            b.vector -= direc;

            this.calcBounds(b);
            b.calcBounds(this);
            this.updateBounds();
            b.updateBounds();
        }
    },

    getBoundOffset: function(b) {
        var diff = this.point - b;
        var angle = (diff.angle + 180) % 360;
        return this.boundOffset[Math.floor(angle / 360 * this.boundOffset.length)];
    },

    calcBounds: function(b) {
        for (var i = 0; i < this.numSegment; i ++) {
            var tp = this.getSidePoint(i);
            var bLen = b.getBoundOffset(tp);
            var td = tp.getDistance(b.point);
            if (td < bLen) {
                this.boundOffsetBuff[i] -= (bLen  - td) / 2;
            }
        }
    },

    getSidePoint: function(index) {
        return this.point + this.sidePoints[index] * this.boundOffset[index];
    },

    updateBounds: function() {
        return;
        //for (var i = 0; i < this.numSegment; i ++)
        //  this.boundOffset[i] = this.boundOffsetBuff[i];
    }
};

//--------------------- main ---------------------

var balls = [];
var numBalls = 18;
for (var i = 0; i < numBalls; i++) {
    var position = new Point(Math.random() * view.size.width, view.size.height);//Point.random() * view.size;
    var vector = new Point({
        angle: 270,//360 * Math.random(),
        length: Math.random() * 3//10
    });
    var radius = 10;//Math.random() * 60 + 60;
    balls.push(new Ball(radius, position, vector));
}

function onFrame() {
    for (var i = 0; i < balls.length - 1; i++) {
        for (var j = i + 1; j < balls.length; j++) {
            balls[i].react(balls[j]);
        }
    }
    for (var i = 0, l = balls.length; i < l; i++) {
        balls[i].iterate();
    }
}


text:
module PlayerRequestHelper
  def make_valid_player_param_hash(player)
    param = player.attributes
    param.delete 'id'
    param
  end

  def make_invalid_player_param_hash(player)
    param = make_valid_player_param_hash(player)
    param['name'] = ''
    param
  end
end

RSpec.configure do |config|
  config.include PlayerRequestHelper, type: :controller
end


text:
class CreateWupeeNotificationTypeConfigurations < ActiveRecord::Migration
  def change
    create_table :wupee_notification_type_configurations do |t|
      t.belongs_to :notification_type
      t.belongs_to :receiver, polymorphic: true
      t.integer :value, default: 0
      t.timestamps null: false
    end

    add_foreign_key :wupee_notification_type_configurations, :wupee_notification_types, column: :notification_type_id
    add_index :wupee_notification_type_configurations, [:notification_type_id], name: "idx_wupee_notif_type_config_on_notification_type_id"
    add_index :wupee_notification_type_configurations, [:receiver_type, :receiver_id], name: "idx_wupee_notif_typ_config_on_receiver_type_and_receiver_id"
  end
end


text:
title: Assign Roles to Users
description: Learn how to assign roles to a user using the Auth0 Management API. For use with Auth0's API Authorization Core feature set.
topics:
  - authorization
  - mgmt-api
  - roles
  - users
  - user-profile
contentType:
    - how-to
useCase:
  - build-an-app
  - call-api
  - secure-api
---
# Assign Roles to Users

This guide will show you how to assign <dfn data-key="role">[roles](/authorization/concepts/rbac)</dfn> to a user using Auth0's Management API. This task can also be performed [using the Dashboard](/dashboard/guides/users/assign-roles-users). The assigned roles can be used with the API Authorization Core feature set.

<%= include('../../../../authorization/_includes/_enable-authz-core') %>

1. Make a `POST` call to the [Assign User Roles endpoint](/api/management/v2#!/Users/post_user_roles). Be sure to replace `USER_ID`, `MGMT_API_ACCESS_TOKEN`, and `ROLE_ID` placeholder values with your user ID, Management API Access Token, and role ID(s), respectively.

```har
{
	"method": "POST",
	"url": "https://${account.namespace}/api/v2/users/USER_ID/roles",
	"headers": [
    { "name": "Content-Type", "value": "application/json" },
   	{ "name": "Authorization", "value": "Bearer MGMT_API_ACCESS_TOKEN" },
    { "name": "Cache-Control", "value": "no-cache" }
	],
	"postData": {
    "mimeType": "application/json",
    "text" : "{ \"roles\": [ \"ROLE_ID\", \"ROLE_ID\" ] }"
	}
}
```

| **Value** | **Description** |
| - | - |
| `USER_ID` | Τhe ID of the user to be updated. |
| `MGMT_API_ACCESS_TOKEN` | [Access Token for the Management API](/api/management/v2/tokens) with the <dfn data-key="scope">scopes</dfn> `read:roles` and `update:users`. |
| `ROLE_ID` | ID(s) of the role(s) you would like to add for the specified user. |