text:
@class CBCentralManager, CLLocationManager, NSArray, NSMutableArray, NSMutableDictionary, NSString;

@interface ShakeRangingBeaconsMgr : MMService <CLLocationManagerDelegate, CBCentralManagerDelegate, MMConfigMgrExt, MMService>
{
    _Bool _isHaveShowed;
    CLLocationManager *_locationManager;
    CBCentralManager *_manager;
    NSMutableDictionary *_beaconsDict;
    NSArray *_uuidsArr;
    double _startRangingTime;
}

@property(nonatomic) double startRangingTime; // @synthesize startRangingTime=_startRangingTime;
@property(retain, nonatomic) NSArray *uuidsArr; // @synthesize uuidsArr=_uuidsArr;
@property(retain) NSMutableDictionary *beaconsDict; // @synthesize beaconsDict=_beaconsDict;
@property(retain, nonatomic) CBCentralManager *manager; // @synthesize manager=_manager;
@property(retain) CLLocationManager *locationManager; // @synthesize locationManager=_locationManager;
@property _Bool isHaveShowed; // @synthesize isHaveShowed=_isHaveShowed;
- (void).cxx_destruct;
- (void)onMMConfigUpdated;
- (void)centralManagerDidUpdateState:(id)arg1;
- (_Bool)haveStartRangingRegion:(id)arg1;
- (void)registerRangingRegions;
- (void)detectBluetoothAvailable;
- (id)keyForBeacon:(id)arg1;
- (void)locationManager:(id)arg1 didFailWithError:(id)arg2;
- (void)locationManager:(id)arg1 rangingBeaconsDidFailForRegion:(id)arg2 withError:(id)arg3;
- (void)locationManager:(id)arg1 didRangeBeacons:(id)arg2 inRegion:(id)arg3;
- (_Bool)isDeviceBLEPowerOn;
- (void)stopRanging;
- (void)startRanging;
@property(readonly) NSMutableArray *beacons;
- (void)setupUUIDs;
- (id)init;
- (void)dealloc;
- (id)loadGatedLaunchOptionsFromFile;
- (_Bool)saveGatedLaunchOptions:(id)arg1;
- (id)gatedLaunchOptionFilePath;

// Remaining properties
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;

@end


text:
    "http://toolbarqueries.clients.google.com:80/tbproxy/af/query"
#define AUTO_FILL_UPLOAD_SERVER_REQUEST_URL \
    "http://toolbarqueries.clients.google.com:80/tbproxy/af/upload"
#define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "GFE/"

namespace {
const size_t kMaxFormCacheSize = 16;
};

struct AutofillDownloadManager::FormRequestData {
  std::vector<std::string> form_signatures;
  AutofillRequestType request_type;
};

AutofillDownloadManager::AutofillDownloadManager(Profile* profile)
    : profile_(profile),
      observer_(NULL),
      max_form_cache_size_(kMaxFormCacheSize),
      next_query_request_(base::Time::Now()),
      next_upload_request_(base::Time::Now()),
      positive_upload_rate_(0),
      negative_upload_rate_(0),
      fetcher_id_for_unittest_(0) {
  // |profile_| could be NULL in some unit-tests.
  if (profile_) {
    PrefService* preferences = profile_->GetPrefs();
    positive_upload_rate_ =
        preferences->GetDouble(prefs::kAutofillPositiveUploadRate);
    negative_upload_rate_ =
        preferences->GetDouble(prefs::kAutofillNegativeUploadRate);
  }
}

AutofillDownloadManager::~AutofillDownloadManager() {
  STLDeleteContainerPairFirstPointers(url_fetchers_.begin(),
                                      url_fetchers_.end());
}

void AutofillDownloadManager::SetObserver(
    AutofillDownloadManager::Observer *observer) {
  if (observer) {
    DCHECK(!observer_);
    observer_ = observer;
  } else {
    observer_ = NULL;
  }
}

bool AutofillDownloadManager::StartQueryRequest(
    const ScopedVector<FormStructure>& forms,
    const AutofillMetrics& metric_logger) {
  if (next_query_request_ > base::Time::Now()) {
    // We are in back-off mode: do not do the request.
    return false;
  }
  std::string form_xml;
  FormRequestData request_data;
  if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures,
                                         &form_xml)) {
    return false;
  }

  request_data.request_type = AutofillDownloadManager::REQUEST_QUERY;
  metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_SENT);

  std::string query_data;
  if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) {
    VLOG(1) << "AutofillDownloadManager: query request has been retrieved from"
            << "the cache";
    if (observer_)
      observer_->OnLoadedAutofillHeuristics(query_data);
    return true;
  }

  return StartRequest(form_xml, request_data);
}

bool AutofillDownloadManager::StartUploadRequest(
    const FormStructure& form,
    bool form_was_autofilled,
    const FieldTypeSet& available_field_types) {
  if (next_upload_request_ > base::Time::Now()) {
    // We are in back-off mode: do not do the request.
    VLOG(1) << "AutofillDownloadManager: Upload request is throttled.";
    return false;
  }

  // Flip a coin to see if we should upload this form.
  double upload_rate = form_was_autofilled ? GetPositiveUploadRate() :
                                             GetNegativeUploadRate();
  if (base::RandDouble() > upload_rate) {
    VLOG(1) << "AutofillDownloadManager: Upload request is ignored.";
    // If we ever need notification that upload was skipped, add it here.
    return false;
  }

  std::string form_xml;
  if (!form.EncodeUploadRequest(available_field_types, form_was_autofilled,
                                &form_xml))
    return false;

  FormRequestData request_data;
  request_data.form_signatures.push_back(form.FormSignature());
  request_data.request_type = AutofillDownloadManager::REQUEST_UPLOAD;

  return StartRequest(form_xml, request_data);
}

bool AutofillDownloadManager::CancelRequest(
    const std::string& form_signature,
    AutofillDownloadManager::AutofillRequestType request_type) {
  for (std::map<URLFetcher *, FormRequestData>::iterator it =
       url_fetchers_.begin();
       it != url_fetchers_.end();
       ++it) {
    if (std::find(it->second.form_signatures.begin(),
        it->second.form_signatures.end(), form_signature) !=
        it->second.form_signatures.end() &&
        it->second.request_type == request_type) {
      delete it->first;
      url_fetchers_.erase(it);
      return true;
    }
  }
  return false;
}

double AutofillDownloadManager::GetPositiveUploadRate() const {
  return positive_upload_rate_;
}

double AutofillDownloadManager::GetNegativeUploadRate() const {
  return negative_upload_rate_;
}

void AutofillDownloadManager::SetPositiveUploadRate(double rate) {
  if (rate == positive_upload_rate_)
    return;
  positive_upload_rate_ = rate;
  DCHECK_GE(rate, 0.0);
  DCHECK_LE(rate, 1.0);
  DCHECK(profile_);
  PrefService* preferences = profile_->GetPrefs();
  preferences->SetDouble(prefs::kAutofillPositiveUploadRate, rate);
}

void AutofillDownloadManager::SetNegativeUploadRate(double rate) {
  if (rate == negative_upload_rate_)
    return;
  negative_upload_rate_ = rate;
  DCHECK_GE(rate, 0.0);
  DCHECK_LE(rate, 1.0);
  DCHECK(profile_);
  PrefService* preferences = profile_->GetPrefs();
  preferences->SetDouble(prefs::kAutofillNegativeUploadRate, rate);
}

bool AutofillDownloadManager::StartRequest(
    const std::string& form_xml,
    const FormRequestData& request_data) {
  net::URLRequestContextGetter* request_context =
      Profile::GetDefaultRequestContext();
  // Check if default request context is NULL: this very rarely happens,
  // I think, this could happen only if user opens chrome with some pages
  // loading the forms immediately; I cannot reproduce this even in that
  // scenario, but bug 74492 shows it happened at least once. In that case bail
  // out and fall back on our own heuristics.
  if (!request_context)
    return false;
  std::string request_url;
  if (request_data.request_type == AutofillDownloadManager::REQUEST_QUERY)
    request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL;
  else
    request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL;

  // Id is ignored for regular chrome, in unit test id's for fake fetcher
  // factory will be 0, 1, 2, ...
  URLFetcher *fetcher = URLFetcher::Create(fetcher_id_for_unittest_++,
                                           GURL(request_url),
                                           URLFetcher::POST,
                                           this);
  url_fetchers_[fetcher] = request_data;
  fetcher->set_automatically_retry_on_5xx(false);
  fetcher->set_request_context(request_context);
  fetcher->set_upload_data("text/plain", form_xml);
  fetcher->Start();
  return true;
}

void AutofillDownloadManager::CacheQueryRequest(
    const std::vector<std::string>& forms_in_query,
    const std::string& query_data) {
  std::string signature = GetCombinedSignature(forms_in_query);
  for (QueryRequestCache::iterator it = cached_forms_.begin();
       it != cached_forms_.end(); ++it) {
    if (it->first == signature) {
      // We hit the cache, move to the first position and return.
      std::pair<std::string, std::string> data = *it;
      cached_forms_.erase(it);
      cached_forms_.push_front(data);
      return;
    }
  }
  std::pair<std::string, std::string> data;
  data.first = signature;
  data.second = query_data;
  cached_forms_.push_front(data);
  while (cached_forms_.size() > max_form_cache_size_)
    cached_forms_.pop_back();
}

bool AutofillDownloadManager::CheckCacheForQueryRequest(
    const std::vector<std::string>& forms_in_query,
    std::string* query_data) const {
  std::string signature = GetCombinedSignature(forms_in_query);
  for (QueryRequestCache::const_iterator it = cached_forms_.begin();
       it != cached_forms_.end(); ++it) {
    if (it->first == signature) {
      // We hit the cache, fill the data and return.
      *query_data = it->second;
      return true;
    }
  }
  return false;
}

std::string AutofillDownloadManager::GetCombinedSignature(
    const std::vector<std::string>& forms_in_query) const {
  size_t total_size = forms_in_query.size();
  for (size_t i = 0; i < forms_in_query.size(); ++i)
    total_size += forms_in_query[i].length();
  std::string signature;

  signature.reserve(total_size);

  for (size_t i = 0; i < forms_in_query.size(); ++i) {
    if (i)
      signature.append(",");
    signature.append(forms_in_query[i]);
  }
  return signature;
}

void AutofillDownloadManager::OnURLFetchComplete(
    const URLFetcher* source,
    const GURL& url,
    const net::URLRequestStatus& status,
    int response_code,
    const net::ResponseCookies& cookies,
    const std::string& data) {
  std::map<URLFetcher *, FormRequestData>::iterator it =
      url_fetchers_.find(const_cast<URLFetcher*>(source));
  if (it == url_fetchers_.end()) {
    // Looks like crash on Mac is possibly caused with callback entering here
    // with unknown fetcher when network is refreshed.
    return;
  }
  std::string type_of_request(
      it->second.request_type == AutofillDownloadManager::REQUEST_QUERY ?
          "query" : "upload");
  const int kHttpResponseOk = 200;
  const int kHttpInternalServerError = 500;
  const int kHttpBadGateway = 502;
  const int kHttpServiceUnavailable = 503;

  CHECK(it->second.form_signatures.size());
  if (response_code != kHttpResponseOk) {
    bool back_off = false;
    std::string server_header;
    switch (response_code) {
      case kHttpBadGateway:
        if (!source->response_headers()->EnumerateHeader(NULL, "server",
                                                         &server_header) ||
            StartsWithASCII(server_header.c_str(),
                            AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER,
                            false) != 0)
          break;
        // Bad gateway was received from Autofill servers. Fall through to back
        // off.
      case kHttpInternalServerError:
      case kHttpServiceUnavailable:
        back_off = true;
        break;
    }

    if (back_off) {
      base::Time back_off_time(base::Time::Now() + source->backoff_delay());
      if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) {
        next_query_request_ = back_off_time;
      } else {
        next_upload_request_ = back_off_time;
      }
    }

    LOG(WARNING) << "AutofillDownloadManager: " << type_of_request
                 << " request has failed with response " << response_code;
    if (observer_) {
      observer_->OnHeuristicsRequestError(it->second.form_signatures[0],
                                          it->second.request_type,
                                          response_code);
    }
  } else {
    VLOG(1) << "AutofillDownloadManager: " << type_of_request
            << " request has succeeded";
    if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) {
      CacheQueryRequest(it->second.form_signatures, data);
      if (observer_)
        observer_->OnLoadedAutofillHeuristics(data);
    } else {
      double new_positive_upload_rate = 0;
      double new_negative_upload_rate = 0;
      AutofillUploadXmlParser parse_handler(&new_positive_upload_rate,
                                            &new_negative_upload_rate);
      buzz::XmlParser parser(&parse_handler);
      parser.Parse(data.data(), data.length(), true);
      if (parse_handler.succeeded()) {
        SetPositiveUploadRate(new_positive_upload_rate);
        SetNegativeUploadRate(new_negative_upload_rate);
      }

      if (observer_)
        observer_->OnUploadedAutofillHeuristics(it->second.form_signatures[0]);
    }
  }
  delete it->first;
  url_fetchers_.erase(it);
}

redpajama_set_name: RedPajamaGithub


text:
package dockerlocal

import (
	"archive/tar"
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/docker/docker/api/types"
	"github.com/google/shlex"
	"github.com/pborman/uuid"
	"github.com/wercker/wercker/auth"
	"github.com/wercker/wercker/core"
	"github.com/wercker/wercker/util"
	"golang.org/x/net/context"
)

// DockerBuildStep needs to implement Step
type DockerBuildStep struct {
	*core.BaseStep
	options            *core.PipelineOptions
	dockerOptions      *Options
	data               map[string]string
	tag                string
	logger             *util.LogEntry
	dockerfile         string
	extrahosts         []string
	q                  bool
	squash             bool
	buildargs          map[string]*string
	labels             map[string]string
	nocache            bool
	authConfigs        map[string]types.AuthConfig
	dockerBuildContext string
}

// NewDockerBuildStep is a special step for doing docker builds
func NewDockerBuildStep(stepConfig *core.StepConfig, options *core.PipelineOptions, dockerOptions *Options) (*DockerBuildStep, error) {
	name := "docker-build"
	displayName := "docker build"
	if stepConfig.Name != "" {
		displayName = stepConfig.Name
	}

	// Add a random number to the name to prevent collisions on disk
	stepSafeID := fmt.Sprintf("%s-%s", name, uuid.NewRandom().String())

	baseStep := core.NewBaseStep(core.BaseStepOptions{
		DisplayName: displayName,
		Env:         &util.Environment{},
		ID:          name,
		Name:        name,
		Owner:       "wercker",
		SafeID:      stepSafeID,
		Version:     util.Version(),
	})

	return &DockerBuildStep{
		BaseStep:      baseStep,
		data:          stepConfig.Data,
		logger:        util.RootLogger().WithField("Logger", "DockerBuildStep"),
		options:       options,
		dockerOptions: dockerOptions,
	}, nil
}

func (s *DockerBuildStep) configure(env *util.Environment) error {
	if imagename, ok := s.data["image-name"]; ok {
		// note that Execute() fails the step (naming the image-name property) if this is not set
		// we don't let the user specify the tag directly, but prepend it with the build ID
		s.tag = s.options.RunID + env.Interpolate(imagename)
	}

	if dockerfile, ok := s.data["dockerfile"]; ok {
		s.dockerfile = env.Interpolate(dockerfile)
	}

	if labelsProp, ok := s.data["labels"]; ok {
		parsedLabels, err := shlex.Split(labelsProp)
		if err == nil {
			labelMap := make(map[string]string)
			for _, labelPair := range parsedLabels {
				pair := strings.Split(labelPair, "=")
				labelMap[env.Interpolate(pair[0])] = env.Interpolate(pair[1])
			}
			s.labels = labelMap
		}
	}

	if buildargsProp, ok := s.data["build-args"]; ok {
		parsedArgs, err := shlex.Split(buildargsProp)
		if err == nil {
			s.buildargs = make(map[string]*string)
			for _, labelPair := range parsedArgs {
				pair := strings.Split(labelPair, "=")
				name := env.Interpolate(pair[0])
				value := env.Interpolate(pair[1])
				s.buildargs[name] = &value
			}
		}
	}

	s.q = false // default to false (verbose) when value is bad or not set
	if qProp, ok := s.data["q"]; ok {
		q, err := strconv.ParseBool(qProp)
		if err == nil {
			s.q = q
		}
	}

	s.nocache = false // default to false when value is bad or not set
	if nocacheProp, ok := s.data["no-cache"]; ok {
		nocache, err := strconv.ParseBool(nocacheProp)
		if err == nil {
			s.nocache = nocache
		}
	}

	if extrahostsProp, ok := s.data["extra-hosts"]; ok {
		parsedExtrahosts, err := shlex.Split(extrahostsProp)
		if err == nil {
			interpolatedExtrahosts := make([]string, len(parsedExtrahosts))
			for i, thisExtrahost := range parsedExtrahosts {
				interpolatedExtrahosts[i] = env.Interpolate(thisExtrahost)
			}
			s.extrahosts = interpolatedExtrahosts
		}
	}

	s.squash = false // default to false (do not squash) when value is bad or not set
	if squashProp, ok := s.data["squash"]; ok {
		squash, err := strconv.ParseBool(squashProp)
		if err == nil {
			s.squash = squash
		}
	}

	if registryAuthConfig, ok := s.data["registry-auth-config"]; ok {
		in := []byte(registryAuthConfig)
		var raw map[string]types.AuthConfig
		err := json.Unmarshal(in, &raw)
		if err != nil {
			return err
		}
		authConfigs := make(map[string]types.AuthConfig)
		for key, value := range raw {
			registry := dockerauth.NormalizeRegistry(env.Interpolate(key))
			if registry != "" {
				if value.Username != "" && value.Password != "" {
					authConfig := types.AuthConfig{
						Username: env.Interpolate(value.Username),
						Password: env.Interpolate(value.Password),
					}
					authConfigs[registry] = authConfig
				}
			}
		}
		s.authConfigs = authConfigs
	}

	if dockerBuildContext, ok := s.data["context"]; ok {
		s.dockerBuildContext = env.Interpolate(dockerBuildContext)
	}
	return nil
}

// InitEnv parses our data into our config
func (s *DockerBuildStep) InitEnv(ctx context.Context, env *util.Environment) error {
	err := s.configure(env)
	if err != nil {
		return err
	}
	return nil
}

// Fetch NOP
func (s *DockerBuildStep) Fetch() (string, error) {
	// nop
	return "", nil
}

// Execute builds an image
func (s *DockerBuildStep) Execute(ctx context.Context, sess *core.Session) (int, error) {
	s.logger.Debugln("Starting DockerBuildStep", s.data)

	if s.tag == "" {
		return -1, errors.New("image-name not set")
	}

	tarfileName := "currentSourceUnderRoot.tar"
	err := s.buildTarfile(ctx, sess, tarfileName)
	if err != nil {
		return -1, err
	}
	return s.buildImage(ctx, sess, tarfileName)
}

// buildTarfile creates the tarfile that will be sent to the daemon to perform the docker build
func (s *DockerBuildStep) buildTarfile(ctx context.Context, sess *core.Session, tarfileName string) error {

	// This is clearly only relevant to docker so we're going to dig into the
	// transport internals a little bit to get the container ID
	dt := sess.Transport().(*DockerTransport) //              TODO Change this to use code which doesn't use fsouza client
	containerID := dt.containerID

	// Extract the /pipeline/source directory from the running pipeline container
	// and save it as a tarfile currentSource.tar
	_, err := s.CollectArtifact(ctx, containerID)
	if err != nil {
		return err
	}

	// In currentSource.tar, the source directory is in /source
	// Copy all the files that are under /source in currentSource.tar
	// into the / directory of a new tarfile with the specified name
	// This will be the tar we sent to the docker build command
	err = s.buildInputTar("currentSource.tar", tarfileName)
	if err != nil {
		return err
	}
	return nil
}

// buildImage builds an image by running the docker BuildImage function with  the specified tarfile
func (s *DockerBuildStep) buildImage(ctx context.Context, sess *core.Session, tarfileName string) (int, error) {
	s.logger.Debugln("Starting DockerBuildStep", s.data)

	officialClient, err := NewOfficialDockerClient(s.dockerOptions)
	if err != nil {
		return 1, err
	}

	e, err := core.EmitterFromContext(ctx)
	if err != nil {
		return 1, err
	}

	tarFile, err := os.Open(s.options.HostPath(tarfileName))
	tarReader := bufio.NewReader(tarFile)

	s.logger.Debugln("Build image")

	// Note: This is a little hack; if a network was not passed through a flag,
	//       then s.options.DockerNetworkName will contain the generated name.
	networkName := s.dockerOptions.NetworkName
	if networkName == "" {
		networkName = s.options.DockerNetworkName
	}

	officialBuildOpts := types.ImageBuildOptions{
		Dockerfile:     s.dockerfile,
		Tags:           []string{s.tag},
		BuildArgs:      s.buildargs,
		SuppressOutput: s.q,
		Remove:         s.options.ShouldRemove, // remove intermediate containers when successful unless --no-remove specified in CLI
		ForceRemove:    s.options.ShouldRemove, // remove intermediate containers when unsuccessful unless --no-remove specified in CLI
		Labels:         s.labels,
		ExtraHosts:     s.extrahosts,
		Squash:         s.squash,
		PullParent:     !s.dockerOptions.Local, // always pull images unless docker-local is specified
		NoCache:        s.nocache,
		NetworkMode:    networkName,
		AuthConfigs:    s.authConfigs,
	}

	imageBuildResponse, err := officialClient.ImageBuild(ctx, tarReader, officialBuildOpts)
	if err != nil {
		s.logger.Errorln("Failed to build image:", err)
		return -1, err
	}

	err = EmitStatus(e, imageBuildResponse.Body, s.options)
	if err != nil {
		return -1, err
	}
	imageBuildResponse.Body.Close()

	s.logger.Debug("Image built")
	return 0, nil
}

// CollectFile NOP
func (s *DockerBuildStep) CollectFile(a, b, c string, dst io.Writer) error {
	return nil
}

// CollectArtifact copies the /pipeline/source directory from the running pipeline container
// and saves it as a directory currentSource and a tarfile currentSource.tar
func (s *DockerBuildStep) CollectArtifact(ctx context.Context, containerID string) (*core.Artifact, error) {
	artificer := NewArtificer(s.options, s.dockerOptions)

	artifact := &core.Artifact{
		ContainerID:   containerID,
		GuestPath:     s.options.GuestPath("source"),
		HostPath:      s.options.HostPath("currentSource"),
		HostTarPath:   s.options.HostPath("currentSource.tar"),
		ApplicationID: s.options.ApplicationID,
		RunID:         s.options.RunID,
		Bucket:        s.options.S3Bucket,
	}

	s.logger.WithFields(util.LogFields{
		"ContainerID":   artifact.ContainerID,
		"GuestPath":     artifact.GuestPath,
		"HostPath":      artifact.HostPath,
		"HostTarPath":   artifact.HostTarPath,
		"ApplicationID": artifact.ApplicationID,
		"RunID":         artifact.RunID,
		"Bucket":        artifact.Bucket,
	}).Debugln("Collecting artifacts from container to ", artifact.HostTarPath)

	fullArtifact, err := artificer.Collect(ctx, artifact)
	if err != nil {
		return nil, err
	}
	return fullArtifact, nil
}

func (s *DockerBuildStep) buildInputTar(sourceTar string, destTar string) error {
	// In currentSource.tar, the source directory is in /source
	// Copy all the files that are under /source/ + context in currentSource.tar
	// into the / directory of a new tarfile currentSourceInRoot.tar
	artifactReader, err := os.Open(s.options.HostPath(sourceTar))
	if err != nil {
		return err
	}
	defer artifactReader.Close()

	s.logger.Debugln("Building input tar", s.options.HostPath(destTar))

	layerFile, err := os.OpenFile(s.options.HostPath(destTar), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}
	defer layerFile.Close()

	tr := tar.NewReader(artifactReader)
	tw := tar.NewWriter(layerFile)

	dockerBuildContext := "source"
	if s.dockerBuildContext != "" {
		dockerBuildContext = filepath.Join(dockerBuildContext, s.dockerBuildContext)
	}
	dockerBuildContext = dockerBuildContext + string(os.PathSeparator)

	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// finished the tarball
			err = tw.Close()
			if err != nil {
				return err
			}
			break
		}

		if err != nil {
			return err
		}

		// Skip the base dir
		if hdr.Name == "./" {
			continue
		}

		// Copy files under the specified build context into the root of the new tar
		if strings.HasPrefix(hdr.Name, dockerBuildContext) {
			hdr.Name = hdr.Name[len(dockerBuildContext):]
		} else {
			continue
		}

		tw.WriteHeader(hdr)
		_, err = io.Copy(tw, tr)
		if err != nil {
			return err
		}

	}
	return nil
}

// ReportPath NOP
func (s *DockerBuildStep) ReportPath(...string) string {
	// for now we just want something that doesn't exist
	return uuid.NewRandom().String()
}

// ShouldSyncEnv before running this step = TRUE
func (s *DockerBuildStep) ShouldSyncEnv() bool {
	// If disable-sync is set, only sync if it is not true
	if disableSync, ok := s.data["disable-sync"]; ok {
		return disableSync != "true"
	}
	return true
}


text:
ChicagoCube::Application.routes.draw do

  # redirects
  match '/form' => redirect('/flower/new')

  get '/instagram' => 'home#instagram'

  get '/flower/new' => 'flowers#new'
  post '/flower/new' => 'flowers#create'
  match '/flower/:id' => 'flowers#show'

  get "/about" => 'home#about'
  get "/contact" => 'home#contact'
  root :to => 'home#index'
end


text:
require 'spec_helper'

describe Knowtify do
  describe '#config' do
    it { expect(Knowtify.config).to be_a(Knowtify::Config) }
  end
end


text:
namespace pst.encodables.ndb
{
    class Root
    {
        public int Reserved { get; }

        public long FileEOF { get; }

        public long AMapLast { get; }

        public long AMapFree { get; }

        public long PMapFree { get; }

        public BREF NBTRootPage { get; }

        public BREF BBTRootPage { get; }

        public int AMapValid { get; }

        public int BReserved { get; }

        public int WReserved { get; }

        public Root(
            int reserved,
            long fileEOF,
            long amapLast,
            long amapFree,
            long pmapFree,
            BREF nbtRootPage,
            BREF bbtRootPage,
            int amapValid,
            int bReserved,
            int wReserved)
        {
            Reserved = reserved;
            FileEOF = fileEOF;
            AMapLast = amapLast;
            AMapFree = amapFree;
            PMapFree = pmapFree;
            NBTRootPage = nbtRootPage;
            BBTRootPage = bbtRootPage;
            AMapValid = amapValid;
            BReserved = bReserved;
            WReserved = wReserved;
        }
    }
}


text:
require 'httparty'
require 'virtus'

module MarvelApi
  class NotImplementedError < StandardError; end

  class ApiModel
    include ::Virtus.model

    def self.all
      new.all
    end

    def host
      "gateway.marvel.com"
    end

    def path
      "#{version}/#{visibility}/#{endpoint}"
    end

    def url
      "http://#{host}/#{path}"
    end

    def version
      "v1"
    end

    def visibility
      "public"
    end

    def endpoint
      raise NotImplementedError
    end

    def options(params={})
      ts = Time.now.to_i
      {
        apikey: MarvelApi.api_key,
        ts: ts,
        hash: hexdigest(ts)
      }.merge(params)
    end

    def hexdigest(ts)
      Digest::MD5.hexdigest(digest_string(ts))
    end

    def digest_string(ts)
      "#{ts}#{MarvelApi.private_key}#{MarvelApi.api_key}"
    end

    def option_key_values
      [].tap do |params|
        options.each_pair do |k, v|
          params << "#{k}=#{v}"
        end
      end.join("&")
    end

    def full_path
      "#{url}?#{option_key_values}"
    end

    def all
      HTTParty.get(full_path)
    end
  end
end


text:
Cache busts static files referenced in your cshtml files.

## Usage
1. In `Startup.ConfigureServices`, add the following:
```c#
services.AddCacheBusting();
```
2. In either your `_ViewImports.cshtml` or your specific view, add the following:
```cshtml
@using PTrampert.Webpack.CacheBuster
@addTagHelper "*, PTrampert.Webpack.CacheBuster"
```

3. You can now use the `cache-bust` attribute in your script and link tags.
```html
<!-- This assumes you have a file in your webroot called `index.js` -->
<script cache-bust="~/index.js"></script>
<!-- This tag would be rendered as <script src="/web/root/path/index.js?v=[chunkhash]"></script> -->
```


text:
The dijit CheckBox Tree, github project [cbtree](https://github.com/pjekel/cbtree),
is a dijit widget extending the dijit/Tree. The CheckBox Tree, stores and associated
models are highly configurable providing support for, amongst others:

* Multi state checkboxes (checked/unchecked/mixed).
* Parent-Child checkbox relationship.
* Read-Only checkboxes
* Tree Styling and Custom Icons

All dijit CheckBox Tree, model and store modules are fully AMD compliant, the
CheckBox Tree comes with a set of extensions allowing the user to enhance and
programmatically control every aspect of the tree. All extensions are optional
therefore, if the user does not require the functionality they do not need to be
loaded:

1. [Tree Styling](https://github.com/pjekel/cbtree/wiki/Tree-Styling)
2. [Tree in HTML forms](https://github.com/pjekel/cbtree/wiki/CheckBox-Tree-in-Forms)
2. [Store Model extension](https://github.com/pjekel/cbtree/wiki/Model-Extension)
3. [Store CORS support](https://github.com/pjekel/cbtree/wiki/Store#cors-support)
4. [Store Ancestry](https://github.com/pjekel/cbtree/wiki/Ancestry-Extension)

### The CheckBox
The use of checkboxes is configurable and enabled by default. The CheckBox Tree
uses it own so called multi-state checkbox to represent the checked state of a
data item. However, the user can substitute the multi-state checkbox with any
widget capable of representing a 'checked' state. Whether or not multi-state is
allowed, or dual state only, depends on the store model configuration.

If however, you elect to disable the checkbox feature the CheckBox Tree acts
like the default dijit Tree but still offering some of the additional benifits
like the ability to hide branch and/or leaf icons and all other styling features.

### The Stores
Starting with release **_cbtree-v09-3.0_** the CheckBox Tree package includes a
new set of [stores](https://github.com/pjekel/cbtree/wiki/Store) implementing the
`cbtree/store/api/Store` API. The cbtree store API is an enhancement to the
default `dojo/store/api/Store` API. The following stores are included:

* Memory
* Hierarchy
* ObjectStore
* FileStore

All stores can also be used stand-alone, independent of the CheckBox Tree and
models.

### Parent-Child Relationship
The CheckBox Tree comes with three store models, one of the Store Model features
is the ability to maintain a parent-child relationship.
The parent checked state, represented as a tree branch checkbox, is the composite
state of all its child checkboxes. For example, if the child checkboxes are either
all checked or unchecked the parent will get the same checked or unchecked state.
If however, the children checked state is mixed, that is, some are checked while
others are unchecked, the parent will get a so called 'mixed' state.

### CheckBox Tree Styling
The Tree Styling extension allows you to dynamically manage the tree styling
on a per data item basis. Using the simple to use accessor *set()* you can alter
the icon, label and row styling for the entire tree or just a single data item.
For example: `set("iconClass", "myIcon", item)` changes the css icon class associated
with all tree node instances of a data item, or if you want to change the label
style:

    // As a callback of a CheckBox click event
    function checkBoxClicked (item, nodeWidget, evt) {
      if (nodeWidget.get("checked")) {
        tree.set("labelStyle", {color:"red"}, item);
      }
    }

For a detailed description of [Tree Styling](https://github.com/pjekel/cbtree/wiki/Tree-Styling)
Wiki pages.

CheckBox Tree Demos

The cbtree packages comes with a set of demos each demonstrating the CheckBox
Tree features and capabilities. Two comprehensive demos are available online:

* Live CheckBox Tree demo
* ArcGIS demo with CheckBox Tree

In addition, the CheckBox Tree [wiki](https://github.com/pjekel/cbtree/wiki) has
several tutorials using, for example, the popular ArcGIS API for JavaScript.

CheckBox Tree Documentation

As of release **_cbtree-v09-3.0_** all documentation is available online in the
[cbtree Wiki](https://github.com/pjekel/cbtree/wiki) section and is no longer
included in the distribution.

Checkbox Tree Downloads

The github repository **cbtree** represents the current development stage of the
CheckBox Tree project, also known as the incubation stage. It may contain new,
untested and undocumented features that are not included in any stable build.
No warrenty is provided that such features will be included in future releases.

To get the latest stable version please visit the [download](http://thejekels.com/download/cbtree)
section:

	    Version
	    Date
	    dojo
	    Description

      cbtree-v09.4-0
      Nov-03 2013
      1.8 - 1.9

	New TreeOnSubmit extension adds support for Checkbox Tree in HTML forms.

	Updated documentation and Wiki.

      cbtree-v09.3-0
      May-03 2013
      1.8 - 1.9

	New stores implementing the cbtree/store/api/Store API.

	New models for the new cbtree stores

	New demos combining cbtree with the ArcGIS 3.3 API

	Enhanced Tree Styling

	and much more...

      cbtree-v09.2-0
      Aug-15 2012
      1.8

	Updated The CheckBox Tree to work with dojo 1.8.

	Official release File Store and File Store Model.

	Per store item read-only checkboxes.

	New declarative demos added.

	Updated documentation.

      cbtree-v09.1-0
      Aug-06 2012
      1.7

	A new File Store and File Store Model have been added.

	New and updated demos.

	Updated documentation.

	Minor software updates.

      cbtree-v09.0-0
      May-20 2012
      1.7
      Initial cbtree-AMD release


text:
/**
 *
  Package: MAG - VistA Imaging
  WARNING: Per VHA Directive 2004-038, this routine should not be modified.
  Date Created: Feb 9, 2009
  Site Name:  Washington OI Field Office, Silver Spring, MD
  Developer:  vhaiswwerfej
  Description:

        ;; +--------------------------------------------------------------------+
        ;; Property of the US Government.
        ;; No permission to copy or redistribute this software is given.
        ;; Use of unreleased versions of this software requires the user
        ;;  to execute a written test agreement with the VistA Imaging
        ;;  Development Office of the Department of Veterans Affairs,
        ;;  telephone (301) 734-0100.
        ;;
        ;; The Food and Drug Administration classifies this software as
        ;; a Class II medical device.  As such, it may not be changed
        ;; in any way.  Modifications to this software may result in an
        ;; adulterated medical device under 21CFR820, the use of which
        ;; is considered to be a violation of US Federal Statutes.
        ;; +--------------------------------------------------------------------+

 */
package gov.va.med.imaging.vistaimagingdatasource;

import gov.va.med.GlobalArtifactIdentifier;
import gov.va.med.ImageURNFactory;
import gov.va.med.PatientIdentifier;
import gov.va.med.imaging.AbstractImagingURN;
import gov.va.med.imaging.ImageURN;
import gov.va.med.imaging.artifactsource.ResolvedArtifactSource;
import gov.va.med.imaging.conversion.ImageConversionFilePath;
import gov.va.med.imaging.conversion.ImageConversionUtility;
import gov.va.med.imaging.core.interfaces.exceptions.*;
import gov.va.med.imaging.datasource.ImageDataSourceSpi;
import gov.va.med.imaging.datasource.exceptions.InvalidCredentialsException;
import gov.va.med.imaging.exceptions.URNFormatException;
import gov.va.med.imaging.exchange.business.*;
import gov.va.med.imaging.exchange.enums.ImageQuality;
import gov.va.med.imaging.exchange.enums.StorageProximity;
import gov.va.med.imaging.exchange.storage.ByteBufferBackedImageInputStream;
import gov.va.med.imaging.exchange.storage.DataSourceImageInputStream;
import gov.va.med.imaging.exchange.storage.DataSourceInputStream;
import gov.va.med.imaging.protocol.vista.VistaImagingTranslator;
import gov.va.med.imaging.transactioncontext.TransactionContextFactory;
import gov.va.med.imaging.url.vista.VistaQuery;
import gov.va.med.imaging.url.vista.exceptions.InvalidVistaCredentialsException;
import gov.va.med.imaging.url.vista.exceptions.VistaMethodException;
import gov.va.med.imaging.url.vista.image.ImagingStorageCredentials;
import gov.va.med.imaging.url.vista.storage.VistaImagingShortTermMetadataCache;
import gov.va.med.imaging.url.vista.storage.VistaImagingStorageManager;
import gov.va.med.imaging.vistadatasource.common.VistaCommonUtilities;
import gov.va.med.imaging.vistadatasource.session.VistaSession;
import gov.va.med.imaging.vistaimagingdatasource.common.VistaImagingCommonUtilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;

/**
 * Abstract base VistA Image data source class for implementing the common functionality needed to retrieve an
 * image from VistA.  Most of the functionality necessary is common between versions of the interfaces, those common
 * functions are here.
 *
 * @author vhaiswwerfej
 *
 */
public abstract class AbstractBaseVistaImageService
extends AbstractVistaImagingDataSourceService
implements ImageDataSourceSpi
{
	private final static Logger logger = Logger.getLogger(AbstractBaseVistaImageService.class);
	private final static String IMAGE_LOCATION_OFFLINE = "O";
	private final static String IMAGE_LOCATION_WORM = "W";

	private static VistaImagingShortTermMetadataCache metadataCache =
		new VistaImagingShortTermMetadataCache();

	// Private member variables
	protected ImageConversionUtility imageConversionUtility;

	/**
	 * Return the required version of VistA Imaging necessary to use this service
	 * @return
	 */
	protected abstract String getRequiredVistaImagingVersion();

	protected abstract String getDataSourceVersion();

	/**
	 * @param resolvedArtifactSource
	 * @param protocol
	 */
	public AbstractBaseVistaImageService(ResolvedArtifactSource resolvedArtifactSource, String protocol)
	{
		super(resolvedArtifactSource, protocol);
		if(! (resolvedArtifactSource instanceof ResolvedSite) )
			throw new UnsupportedOperationException("The artifact source must be an instance of ResolvedSite and it is a '" + resolvedArtifactSource.getClass().getSimpleName() + "'.");
	}

	/**
	 * The artifact source must be checked in the constructor to assure that it is an instance
	 * of ResolvedSite.
	 *
	 * @return
	 */
	protected ResolvedSite getResolvedSite()
	{
		return (ResolvedSite)getResolvedArtifactSource();
	}

	protected Site getSite()
	{
		return getResolvedSite().getSite();
	}

	protected abstract HashMap<String, String> getImageHISUpdates(VistaSession vistaSession, Image image)
	throws MethodException, ConnectionException, IOException;

	private VistaSession getVistaSession()
    throws IOException, ConnectionException, MethodException, SecurityCredentialsExpiredException
    {
	    return VistaSession.getOrCreate(getMetadataUrl(), getSite());
    }

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#isVersionCompatible()
	 */
	@Override
	public boolean isVersionCompatible()
	throws SecurityCredentialsExpiredException
	{
		VistaSession localVistaSession = null;
		logger.info("isVersionCompatible searching for version [" + getRequiredVistaImagingVersion() + "], TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
		try
		{
			localVistaSession = getVistaSession();
			return VistaImagingCommonUtilities.isVersionCompatible(getRequiredVistaImagingVersion(), localVistaSession);
		}
		catch(SecurityCredentialsExpiredException sceX)
		{
			// caught here to be sure it gets thrown as SecurityCredentialsExpiredException, not ConnectionException
			throw sceX;
		}
		catch(MethodException mX)
		{
			logger.error("There was an error finding the installed Imaging version from VistA", mX);
			TransactionContextFactory.get().addDebugInformation("isVersionCompatible() failed, " + (mX == null ? "<null error>" : mX.getMessage()));
		}
		catch(ConnectionException cX)
		{
			logger.error("There was an error finding the installed Imaging version from VistA", cX);
			TransactionContextFactory.get().addDebugInformation("isVersionCompatible() failed, " + (cX == null ? "<null error>" : cX.getMessage()));
		}
		catch(IOException ioX)
		{
			logger.error("There was an error finding the installed Imaging version from VistA", ioX);
			TransactionContextFactory.get().addDebugInformation("isVersionCompatible() failed, " + (ioX == null ? "<null error>" : ioX.getMessage()));
		}
		finally
		{
			try{localVistaSession.close();}
			catch(Throwable t){}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImageDevFields(gov.va.med.imaging.AbstractBaseImagingURN, java.lang.String)
	 */
	@Override
	public String getImageDevFields(AbstractImagingURN imagingUrn,
			String flags)
	throws MethodException, ConnectionException, ImageNotFoundException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImageDevFields", getDataSourceVersion());
		// CTB 29Nov2009
		//String imageId = Base32ConversionUtility.base32Decode(imagingUrn.getImagingIdentifier());
		String imageId = imagingUrn.getImagingIdentifier();
		logger.info("getImageDevFields(" + imagingUrn.toString() + ", Base32{" + imageId + "}), TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
		return getImageDevFields(imageId, flags);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImageInformation(gov.va.med.imaging.AbstractBaseImagingURN)
	 */
	@Override
	public String getImageInformation(AbstractImagingURN imagingUrn, boolean includeDeletedImages)
	throws MethodException, ConnectionException, ImageNotFoundException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImageInformation", getDataSourceVersion());
		// CTB 29Nov2009
		//String imageId = Base32ConversionUtility.base32Decode(imagingUrn.getImagingIdentifier());
		String imageId = imagingUrn.getImagingIdentifier();
		logger.info("getImageInformation(" + imagingUrn.toString() + ", Base32{" + imageId + "}), TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
		return getImageInformation(imageId, includeDeletedImages);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImageSystemGlobalNode(gov.va.med.imaging.AbstractBaseImagingURN)
	 */
	@Override
	public String getImageSystemGlobalNode(AbstractImagingURN imagingUrn)
	throws MethodException, ConnectionException, ImageNotFoundException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImageSystemGlobalNode", getDataSourceVersion());
		// CTB 29Nov2009
		//String imageId = Base32ConversionUtility.base32Decode(imagingUrn.getImagingIdentifier());
		String imageId = imagingUrn.getImagingIdentifier();
		logger.info("getImageSystemGlobalNode(" + imagingUrn.toString() + ", Base32{" + imageId + "}), TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
		return getSysGlobalNodes(imageId);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImage(gov.va.med.imaging.exchange.business.Image, gov.va.med.imaging.exchange.business.ImageFormatQualityList)
	 */
	@Override
	public ImageStreamResponse getImage(Image image,
			ImageFormatQualityList requestFormatQualityList)
	throws MethodException, ConnectionException
	{
		VistaSession localVistaSession = null;
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImage", getDataSourceVersion());
		logger.info("getImage(" + image.getIen() + ") from Image object TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");

		try
		{
			String serverShare = VistaImagingTranslator.extractServerShare(image);
			// if for some reason there is no server share found, we are going to look in VistA to get updated
			// image metadata - I'm really not sure why this is happening, but it seems to be happening...
			// really shouldn't but was occuring in unit tests.  If query by Image URN and get image from VistA,
			// the image share was found and all worked properly.
			if((serverShare == null) || (serverShare.length() <= 0))
			{
				logger.info("Got an empty server share from the image object, trying to get new metadata from image Urn");
				ImageURN imageUrn = image.getImageUrn();
				image = getImageObjectFromImageUrn(imageUrn);
				if(image == null)
				{
					String msg = "Got null image metadata back from image Urn, image not found";
					logger.error(msg);
					throw new ImageNotFoundException(msg);
				}
				logger.info("Using new image metadata to extract server share from image [" + imageUrn.toString() + "].");
				serverShare = VistaImagingTranslator.extractServerShare(image);
			}
			ImagingStorageCredentials imagingStorageCredentials = null;

			logger.info("Searching for Imaging Storage Credentials for server share [" + serverShare + "]");
			imagingStorageCredentials = VistaImagingStorageManager.getImagingStorageCredentialsFromCache(image, getSite());
			if(imagingStorageCredentials == null)
			{
				logger.info("Imaging Storage Credentials for site '" + getSite().getSiteNumber() + "' does not exist in the network location cache, getting from VistA");
				// note that we delay getting the vista session until we are sure we need it
				localVistaSession = getVistaSession();
				imagingStorageCredentials = VistaImagingStorageManager.getImagingStorageCredentialsFromVista(localVistaSession, serverShare, getSite());
			}
			else
			{
				logger.info("Imaging Storage Credentials for [" + serverShare + "] found in the network location cache");
			}

			if(imagingStorageCredentials == null)
			{
				String msg = "No Imaging Storage Credentials found for image share [" + serverShare + "] for image [" + image.getFullFilename() + "]";
				logger.error(msg);
				throw new ImageNotFoundException(msg);
			}

			return getImageInternal(localVistaSession, image, requestFormatQualityList, imagingStorageCredentials);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting image", ioX);
			throw new ConnectionException(ioX);
		}
		finally
		{
			try
			{
				if(localVistaSession != null)
					localVistaSession.close();
			}
			catch(Throwable t){}
		}
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImage(gov.va.med.imaging.ImageURN, gov.va.med.imaging.exchange.business.ImageFormatQualityList)
	 */
	@Override
	public ImageStreamResponse getImage(GlobalArtifactIdentifier gai,
		ImageFormatQualityList requestFormatQualityList)
	throws MethodException, ConnectionException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImage", getDataSourceVersion());
		if(!(gai instanceof ImageURN))
		{
			throw new MethodException("GlobalArtifactIdentifier '" + gai.toString() + "' is not instanceof ImageURN, cannot retrieve image from VistA.");
		}
		ImageURN imageUrn = (ImageURN)gai;
		logger.info("getImage(" + imageUrn.toString() + ") from ImageURN TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");

		Image image = getImageObjectFromImageUrn(imageUrn);
		if(image == null)
		{
			//logger.error("Got null image metadata from VistA for image [" + imageUrn.toString() + "], returning null");
			//return null;

			String msg = "Got null image metadata from VistA for image [" + imageUrn.toString() + "], image not found";
			logger.error(msg);
			throw new ImageNotFoundException(msg);
		}

		return getImage(image, requestFormatQualityList);
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImageTXTFile(gov.va.med.imaging.exchange.business.Image)
	 */
	@Override
	public DataSourceInputStream getImageTXTFile(Image image)
			throws MethodException, ConnectionException,
			ImageNotFoundException, ImageNearLineException
	{
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImageTXTFile", getDataSourceVersion());
		VistaSession vistaSession = null;
		try {
			vistaSession = getVistaSession();
			return getImageTXTFileInternal(vistaSession, image);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting image TXT file", ioX);
			throw new ConnectionException(ioX);
		}
		finally
		{
			try{vistaSession.close();}
			catch(Throwable t){}
		}
	}

	/* (non-Javadoc)
	 * @see gov.va.med.imaging.datasource.ImageDataSource#getImageTXTFile(gov.va.med.imaging.ImageURN)
	 */
	@Override
	public DataSourceInputStream getImageTXTFile(ImageURN imageUrn)
			throws MethodException, ConnectionException,
			ImageNotFoundException, ImageNearLineException
	{
		logger.info("getImageTXTFile(" + imageUrn.toString() + ") from ImageURN TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
		VistaCommonUtilities.setDataSourceMethodAndVersion("getImageTXTFile", getDataSourceVersion());

		Image image = getImageObjectFromImageUrn(imageUrn);
		if(image == null)
		{
			String msg = "Got null image metadata from VistA for TXT File [" + imageUrn.toString() + "], TXT File not found";
			logger.error(msg);
			throw new ImageNotFoundException(msg);
		}
		return getImageTXTFile(image);
	}

	protected abstract VistaQuery getImageInformationQuery(String identifier, boolean includeDeletedImages);
	/*
	{
		VistaQuery msg = VistaImagingQueryFactory.createGetImageInformationQuery(identifier);
		return msg;
	}*/

	private String getImageInformation(String identifier, boolean includeDeletedImages)
	throws ConnectionException, MethodException
	{
		VistaSession vistaSession = null;
		VistaQuery msg = getImageInformationQuery(identifier, includeDeletedImages);
		String rtn = null;
		try
		{
			vistaSession = getVistaSession();
			rtn = vistaSession.call(msg);
			logger.info("getImageInformation(" + identifier + "), Got [" + rtn.length() + "] bytes back, TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
			TransactionContextFactory.get().setDataSourceBytesReceived(new Long(rtn.length()));
			return rtn;
		}
		catch(InvalidVistaCredentialsException ivcX)
		{
			logger.error("Error getting image information", ivcX);
			throw new ConnectionException(ivcX);
		}
		catch(VistaMethodException vmX)
		{
			logger.error("Error getting image information", vmX);
			throw new ConnectionException(vmX);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting image information", ioX);
			throw new ConnectionException(ioX);
		}
		finally
		{
			try
			{
				if(vistaSession != null)
					vistaSession.close();
			}
			catch(Throwable t){}
		}
	}

	private String getImageDevFields(String identifier, String flags)
	throws ConnectionException, MethodException
	{
		VistaSession vistaSession = null;
		VistaQuery msg = VistaImagingQueryFactory.createGetDevFieldValues(identifier, flags);
		String rtn = null;
		try
		{
			vistaSession = getVistaSession();
			rtn = vistaSession.call(msg);
			logger.info("getImageDevFields(" + identifier + "), Got [" + rtn.length() + "] bytes back, TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
			TransactionContextFactory.get().setDataSourceBytesReceived(new Long(rtn.length()));
			return rtn;
		}
		catch(InvalidVistaCredentialsException ivcX)
		{
			logger.error("Error getting dev fields", ivcX);
			throw new ConnectionException(ivcX);
		}
		catch(VistaMethodException vmX)
		{
			logger.error("Error getting dev fields", vmX);
			throw new ConnectionException(vmX);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting dev fields", ioX);
			throw new ConnectionException(ioX);
		}
		finally
		{
			try
			{
				if(vistaSession != null)
					vistaSession.close();
			}
			catch(Throwable t){}
		}
	}

	private String getSysGlobalNodes(String identifier)
	throws ConnectionException, MethodException
	{
		VistaSession vistaSession = null;
		VistaQuery msg = VistaImagingQueryFactory.createGetSysGlobalNodesQuery(identifier);
		String rtn = null;
		try
		{
			vistaSession = getVistaSession();
			rtn = vistaSession.call(msg);
			logger.info("getSysGlobalNodes(" + identifier + "), Got [" + rtn.length() + "] bytes back, TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");
			TransactionContextFactory.get().setDataSourceBytesReceived(new Long(rtn.length()));
			return rtn;
		}
		catch(InvalidVistaCredentialsException ivcX)
		{
			logger.error("Error getting system global nodes", ivcX);
			throw new ConnectionException(ivcX);
		}
		catch(VistaMethodException vmX)
		{
			logger.error("Error getting system global nodes", vmX);
			throw new ConnectionException(vmX);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting system global nodes", ioX);
			throw new ConnectionException(ioX);
		}
		finally
		{
			try
			{
				if(vistaSession != null)
					vistaSession.close();
			}
			catch(Throwable t){}
		}
	}

	/**
	 * This function determines if the full image file path is actually the diagnostic image.
	 * Such is the case of CT images where there is no BIG entry, only the full entry.
	 * @param image
	 * @return
	 */
	private boolean isFullDiagnostic(Image image)
	{
		if(image == null)
			return false;
		// if there is a value for the big filename path, then the full path is not diagnostic
		if((image.getBigFilename() != null) && (image.getBigFilename().length() > 0))
			return false;
		return true;
	}

	private Image getCachedImageMetadata(ImageURN imageUrn)
	{
		List<Image> images = metadataCache.getCacheImages(imageUrn);
		if(images != null)
		{
			for(Image image : images)
			{
				if(image.getIen().equals(imageUrn.getImageId()))
				{
					return image;
				}
			}
		}
		return null;
	}

	/**
	 *
	 * @param imageUrn
	 * @return
	 * @throws ConnectionException
	 * @throws MethodException
	 */
	private Image getImageObjectFromImageUrn(ImageURN imageUrn)
	throws ConnectionException, MethodException
	{
		logger.info("findImageFromImageUrn - searching for image metadata for image [" + imageUrn.toString() + "].");

		Image cachedImage = getCachedImageMetadata(imageUrn);
		if(cachedImage != null)
		{
			logger.info("Found image '" + imageUrn.toString() + "' in short term metadata cache.");
			return cachedImage;
		}
		logger.info("Did not find image '" + imageUrn.toString() + "' in short term metadata cache, retrieving from VistA.");
		VistaSession localVistaSession = null;
		// need to query VistA using the decoded study Ien value
		// CTB 29Nov2009
		//String decodedStudyIen = Base32ConversionUtility.base32Decode(imageUrn.getStudyId());
		String decodedStudyIen = imageUrn.getStudyId();
		String siteId = imageUrn.getOriginatingSiteId();
		PatientIdentifier patientIdentifier = imageUrn.getThePatientIdentifier();

		VistaQuery msg = VistaImagingQueryFactory.createGetStudyImagesVistaQuery(decodedStudyIen);
		try
		{
			localVistaSession = getVistaSession();
			String imagesString = localVistaSession.call(msg);
			// if the response starts with an error then the ien for this study might be the actual image, and not a group IEN
			// we need to query for the study groups to get the image data
			if(imagesString.startsWith("0^ERROR"))
			{
				logger.info("Received error response when trying to get group of images, might indicate image is in a single image study");
				Image image = getImageFromGroup(localVistaSession, imageUrn);
				try{localVistaSession.close();}catch(Throwable t){}
				if(image != null)
				{
					return image;
				}
			}
			else
			{
				// the
				List<Image> images = VistaImagingTranslator.VistaImageStringListToImageList(imagesString, siteId,
						decodedStudyIen, patientIdentifier);
				metadataCache.cacheImages(imageUrn, images);
				for(int i = 0; i < images.size(); i++)
				{
					Image image = images.get(i);
					// compare to the base 32 encoded Image id since that is what will be put into the image object by the translator
					if(image.getIen().equals(imageUrn.getImageId()))
					{
						//image.setStudyIen(imageUrn.getStudyId()); // set using the base32 encoded value
						// put the local VistA connection back into the cache here in case it is not used again,
						// if it is needed by getImage then it will be in the cache and available

						// JMW 10/2/2008 - need to set the site number so the network location cache can be used properly.
						//image.setSiteNumber(getSite().getSiteNumber());
						try{localVistaSession.close();}catch(Throwable t){}
						return image;
					}
				}
				logger.info("Did not find image '" + imageUrn.getImageId() + "' in group of images, might indicate image is first image in a multi-image group, getting groups for patient");
				Image image = getImageFromGroup(localVistaSession, imageUrn);
				try{localVistaSession.close();}catch(Throwable t){}
				if(image != null)
				{
					return image;
				}
			}
		}
		catch (URNFormatException x)
		{
			logger.error("Error getting Vista txt file", x);
			throw new ConnectionException(x);
		}
		catch(IOException ioX)
		{
			logger.error("Error getting Vista image", ioX);
			throw new ConnectionException(ioX);
		}
		catch(VistaMethodException vmX)
		{
			logger.error("Error getting Vista image", vmX);
			throw new MethodException(vmX);
		}
		catch(InvalidVistaCredentialsException ivcX)
		{
			logger.error("Error getting Vista image", ivcX);
			throw new ConnectionException(ivcX);
		}
		logger.error("Unable to find image metadata for URN [" + imageUrn.toString() + "]");
		return null;
	}

	private Image getImageFromGroup(VistaSession vistaSession, ImageURN imageUrn)
	throws MethodException, IOException, ConnectionException
	{
		// CTB 29Nov2009
		//String decodedStudyIen = Base32ConversionUtility.base32Decode(imageUrn.getStudyId());
		//String decodedImageIen = Base32ConversionUtility.base32Decode(imageUrn.getImageId());
		String decodedStudyIen = imageUrn.getStudyId();
		String decodedImageIen = imageUrn.getImageId();
		PatientIdentifier patientIdentifier = imageUrn.getThePatientIdentifier();
		logger.info("getImageFromGroup(" + decodedStudyIen + ") TransactionContext (" + TransactionContextFactory.get().getDisplayIdentity() + ").");

		String patientDfn = getPatientDfn(vistaSession, patientIdentifier);
		VistaQuery vm = VistaImagingQueryFactory.createGetGroupsVistaQuery(patientDfn, null);
		String rtn = null;
		try
		{
			rtn = vistaSession.call(vm);
			if(rtn.charAt(0) == '1')
			{
				List<Image> images = VistaImagingTranslator.createImagesForFirstImagesFromVistaGroupList(rtn, patientIdentifier,
						getSite().getSiteNumber());
				for(int i = 0; i < images.size(); i++)
				{
					Image image = images.get(i);
					// CTB 29Nov2009
					//String newDecodedId = Base32ConversionUtility.base32Decode(image.getIen());
					String newDecodedId = image.getIen();
					if(newDecodedId.equals(decodedImageIen))
					{
						//image.setStudyIen(imageUrn.getStudyId());
						return image;
					}
				}
			}
			else if(rtn.startsWith("0^No images for filter"))
			{
				logger.info("0 response from MAG4 PAT GET IMAGES rpc, no images found, [" + rtn + "]");
				throw new ImageNotFoundException("No images found that match [" + decodedStudyIen + "]");
			}
			else if(rtn.startsWith("0^No Such Patient:"))
			{
				logger.info("0 response from MAG4 PAT GET IMAGES rpc, [" + rtn + "]");
				throw new ImageNotFoundException("No patient [ "+ patientIdentifier + "] found in database");
			}
			else
			{
				logger.info("0 response from MAG4 PAT GET IMAGES rpc, [" + rtn + "]");
				throw new ImageNotFoundException(rtn);
			}
		}
		catch (Exception ex)
		{
			logger.error(ex);
			throw new MethodException(ex);
		}

		return null;
	}

	private ImageStreamResponse getImageInternal(VistaSession vistaSession, Image image,
			ImageFormatQualityList requestFormatQualityList, ImagingStorageCredentials networkLocation)
	throws MethodException, ConnectionException, ImageNearLineException, IOException
	{
		boolean gotSession = false;
		try
		{
			DataSourceImageInputStream imageStream = null;
			ImageQuality imageQuality = requestFormatQualityList == null ? null : requestFormatQualityList.getFirstImageQuality();
			List<ImageConversionFilePath> filePaths = getImageFilePaths(vistaSession, image, imageQuality);
			// if any of the file paths start with a '.' we want to use those canned paths if possible
			for(ImageConversionFilePath filePath : filePaths)
			{
				if(filePath.getFilePath().startsWith("."))
				{
					// get a canned image that represents this file
					try
					{
						imageStream = getCannedImage(image, filePath.getFilePath());
						ImageStreamResponse response = new ImageStreamResponse(imageStream);
						response.setImageQuality(filePath.getImageQuality());
						return response;
					}
					catch(FileNotFoundException fnfX)
					{
						logger.error("Error trying to open canned image", fnfX);
						throw new ImageNotFoundException(fnfX);
					}
				}
			}
			HashMap<String, String> hisUpdate = null;
			if(imageQuality != ImageQuality.THUMBNAIL)
			{
				logger.info("About to get HIS update for image [" + image.getIen() + "]");
				if(vistaSession == null)
				{
					vistaSession = getVistaSession();
					gotSession = true;
				}
				hisUpdate = getImageHISUpdates(vistaSession, image);
			}
			return imageConversionUtility.getImage(filePaths, requestFormatQualityList,
				requestFormatQualityList, true, networkLocation, hisUpdate);
		}
		/*
		catch(ImageNotFoundException infX)
		{
			logger.error("Image [" + image.getIen() + "] not found", infX);
			return null;
		}
		*/
		catch(URNFormatException iurnfX)
		{
			logger.error("Error reading image [" + image.getIen() + "]", iurnfX);
			throw new MethodException(iurnfX);
		}
		catch(ConnectionException cX)
		{
			logger.error("Error reading image [" + image.getIen() + "]", cX);
			throw cX;
		}
		catch(IOException ioX)
		{
			logger.error("Error reading image [" + image.getIen() + "]", ioX);
			throw ioX;
		}
		finally
		{
			if((gotSession) && (vistaSession != null))
			{
				try{vistaSession.close();}
				catch(Throwable t){}
			}
		}
	}

	/**
	 * An imageQuality of null indicates that the
	 * @param localVistaSession
	 * @param image
	 * @param imageQuality
	 * @return
	 * @throws ImageNearLineException
	 * @throws URNFormatException
	 * @throws ConnectionException
	 * @throws MethodException
	 * @throws IOException
	 * @throws ImageNotFoundException
	 */
	private List<ImageConversionFilePath> getImageFilePaths(VistaSession localVistaSession, Image image, ImageQuality imageQuality)
	throws ImageNearLineException, URNFormatException, ConnectionException,
	MethodException, IOException, ImageNotFoundException
	{
		List<ImageConversionFilePath> filePaths = new ArrayList<ImageConversionFilePath>();
		boolean gotVistaSession = false;
		// CTB 29Nov2009
		//String decodedImageIen = Base32ConversionUtility.base32Decode(image.getIen());
		String decodedImageIen = image.getIen();
		StorageProximity imageProximity = StorageProximity.ONLINE;
		logger.info("Getting image filename for image [" + image.getIen() + "] with quality [" + imageQuality + "]");
		try
		{
			if(imageQuality == ImageQuality.THUMBNAIL)
			{
				if(image.getAbsFilename().startsWith("-1"))
				{
					logger.error("Image [" + image.getIen() + "] has thumbnail file path [" + image.getAbsFilename() + "], no image to respond with");
					throw new ImageNotFoundException("Image [" + image.getIen() + "] has thumbnail file path [" + image.getAbsFilename() + "], no image to respond with");
				}

				imageProximity = StorageProximity.ONLINE;
				if(IMAGE_LOCATION_OFFLINE.equals(image.getAbsLocation()))
				{
					imageProximity = StorageProximity.OFFLINE;
					if(localVistaSession == null)
					{
						localVistaSession = getVistaSession();
						gotVistaSession = true;
					}
					notifyArchiveOperator(localVistaSession, image.getAbsFilename(), decodedImageIen);
					throw new ImageNearLineException(
						ImageURNFactory.create(
						TransactionContextFactory.get().getRealm(), image.getIen(), image.getStudyIen(), image.getPatientId(), null, ImageURN.class)
					);
				}
				else if(IMAGE_LOCATION_WORM.equals(image.getAbsLocation()))
					imageProximity = StorageProximity.NEARLINE;

				ImageConversionFilePath absPath = new ImageConversionFilePath(image.getAbsFilename(), ImageQuality.THUMBNAIL, imageProximity);
				filePaths.add(absPath);
			}
			// ref request cannot use big file
			else if((imageQuality == ImageQuality.REFERENCE) &&
					(!getResolvedSite().isLocalSite()))
			{
				if(image.getFullFilename().startsWith("-1"))
				{
					logger.error("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
					throw new ImageNotFoundException("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
				}
				logger.info("Returning full image [" + image.getFullFilename() + "] because not local site or ref quality requested");

				imageProximity = StorageProximity.ONLINE;
				if(IMAGE_LOCATION_OFFLINE.equals(image.getFullLocation()))
				{
					imageProximity = StorageProximity.OFFLINE;
					if(localVistaSession == null)
					{
						localVistaSession = getVistaSession();
						gotVistaSession = true;
					}
					notifyArchiveOperator(localVistaSession, image.getFullFilename(), decodedImageIen);
					throw new ImageNearLineException(
						ImageURNFactory.create(
						TransactionContextFactory.get().getRealm(), image.getIen(), image.getStudyIen(),
						image.getPatientId(), null, ImageURN.class)
					);
				}
				else if(IMAGE_LOCATION_WORM.equals(image.getFullLocation()))
					imageProximity = StorageProximity.NEARLINE;

				ImageQuality actualImageQuality = imageQuality;

				if((image.getBigFilename() == null) || (image.getBigFilename().length() <= 0))
				{
					// in this case, the "Full" location is actually the diagnostic image (CT, PDF, DOC, HTML, etc)
					actualImageQuality = ImageQuality.DIAGNOSTICUNCOMPRESSED;
				}
				ImageConversionFilePath imgPath = new ImageConversionFilePath(image.getFullFilename(), actualImageQuality, imageProximity);
				filePaths.add(imgPath);
			}
			else if(imageQuality == ImageQuality.REFERENCE) // ref can use big file
			{
				boolean foundAFile = false;
				imageProximity = StorageProximity.ONLINE;
				if(IMAGE_LOCATION_OFFLINE.equals(image.getFullLocation()))
				{
					imageProximity = StorageProximity.OFFLINE;
					if(localVistaSession == null)
					{
						localVistaSession = getVistaSession();
						gotVistaSession = true;
					}
					notifyArchiveOperator(localVistaSession, image.getFullFilename(), decodedImageIen);
					if ((image.getBigFilename()!=null) && (image.getBigFilename().length() > 0))
					{
						if(localVistaSession == null)
						{
							localVistaSession = getVistaSession();
							gotVistaSession = true;
						}
						notifyArchiveOperator(localVistaSession, image.getBigFilename(), decodedImageIen);
					}
					throw new ImageNearLineException(
						ImageURN.create(
						TransactionContextFactory.get().getRealm(), image.getIen(), image.getStudyIen(), image.getPatientId())
					);
				}
				else if(IMAGE_LOCATION_WORM.equals(image.getFullLocation()))
					imageProximity = StorageProximity.NEARLINE;
				if((image.getBigFilename() != null) && (image.getBigFilename().length() > 0))
				{
					if(image.getBigFilename().startsWith("-1"))
					{
						logger.info("Big filename [" + image.getBigFilename() + "] starts with '-1', not using file path");
					}
					else
					{
						foundAFile = true;
						ImageConversionFilePath bigPath = new ImageConversionFilePath(image.getBigFilename(), ImageQuality.DIAGNOSTICUNCOMPRESSED, imageProximity);
						filePaths.add(bigPath);
					}
				}
				if(image.getFullFilename().startsWith("-1"))
				{
					logger.info("Full filename [" + image.getFullFilename() + "] starts with '-1', not using file path");
				}
				else
				{
					ImageQuality actualQuality = ImageQuality.REFERENCE;
					if(isFullDiagnostic(image))
					{
						actualQuality = ImageQuality.DIAGNOSTICUNCOMPRESSED;
					}
					foundAFile = true;
					ImageConversionFilePath fullPath = new ImageConversionFilePath(image.getFullFilename(), actualQuality, imageProximity);
					filePaths.add(fullPath);
				}

				if(!foundAFile)
				{
					logger.error("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
					throw new ImageNotFoundException("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
				}
			}
			else // diagnostic request
			{
				imageProximity = StorageProximity.ONLINE;
				if(IMAGE_LOCATION_OFFLINE.equals(image.getFullLocation()))
				{
					imageProximity = StorageProximity.OFFLINE;
					if(localVistaSession == null)
					{
						localVistaSession = getVistaSession();
						gotVistaSession = true;
					}
					notifyArchiveOperator(localVistaSession, image.getFullFilename(), decodedImageIen);
					if ((image.getBigFilename()!=null) && (image.getBigFilename().length() > 0))
					{
						if(localVistaSession == null)
						{
							localVistaSession = getVistaSession();
							gotVistaSession = true;
						}
						notifyArchiveOperator(localVistaSession, image.getBigFilename(), decodedImageIen);
					}
					throw new ImageNearLineException(
						ImageURN.create(
						TransactionContextFactory.get().getRealm(), image.getIen(), image.getStudyIen(), image.getPatientId())
					);
				}
				else if(IMAGE_LOCATION_WORM.equals(image.getFullLocation()))
					imageProximity = StorageProximity.NEARLINE;

				if(isFullDiagnostic(image))
				{
					if(image.getFullFilename().startsWith("-1"))
					{
						logger.error("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
						throw new ImageNotFoundException("Image [" + image.getIen() + "] has full file path [" + image.getFullFilename() + "], no image to respond with");
					}
					ImageConversionFilePath filePath = new ImageConversionFilePath(image.getFullFilename(), ImageQuality.DIAGNOSTICUNCOMPRESSED, imageProximity);
					filePaths.add(filePath);
				}
				else
				{
					ImageConversionFilePath filePath = new ImageConversionFilePath(image.getBigFilename(), ImageQuality.DIAGNOSTICUNCOMPRESSED, imageProximity);
					filePaths.add(filePath);
				}
			}
		}
		finally
		{
			if((gotVistaSession) && (localVistaSession != null))
			{
				try{localVistaSession.close();}
				catch(Throwable t){}
			}
		}
		return filePaths;
	}

	/**
	 * Determine the canned image to use to stream back to the user for requesting the thumbnail
	 * @param image
	 * @param filename
	 * @return
	 * @throws FileNotFoundException
	 */
	private DataSourceImageInputStream getCannedImage(Image image, String filename)
	throws FileNotFoundException
	{
		String fname = getVistaImagingConfiguration().getImageAbstract(image.getImgType());// "";
		if((fname == null) || ("".equals(fname)))
		{
			// try to get the path from the filename
			fname = getVistaImagingConfiguration().getImageAbstract(filename);
		}
		if((fname == null) || ("".equals(fname)))
		{
			return null;
		}
		String vixConfigDir = System.getenv("vixconfig");
		vixConfigDir += File.separatorChar + "images" + File.separatorChar;
		fname = vixConfigDir + fname;

		File cannedImage = new File(fname);
		if(cannedImage.exists())
		{
			ByteBufferBackedImageInputStream input =
				new ByteBufferBackedImageInputStream(new FileInputStream(cannedImage),
						(int)cannedImage.length());
			return input;
		}
		return null;
	}

	/**
	 * Runs the RPC necessary to notify the archive operator that a request for an offline image has occured
	 *
	 * @param filename The filename of the image requested
	 * @param imageIen The internal entry number of the image requested
	 * @throws MethodException
	 * @throws ConnectionException
	 * @throws IOException
	 */
	private void notifyArchiveOperator(VistaSession vistaSession, String filename, String imageIen)
	throws MethodException, ConnectionException, IOException
	{
		VistaQuery archiveNotifyQuery = VistaImagingQueryFactory.createNotifyArchiveOperatorQuery(filename, imageIen);
		try
		{
			vistaSession.call(archiveNotifyQuery);
		}
		catch(VistaMethodException vmX)
		{
			logger.error("Error notifying Archive Operator", vmX);
			throw new MethodException(vmX);
		}
		catch(InvalidVistaCredentialsException ivcX)
		{
			logger.error("Error notifying Archive Operator", ivcX);
			throw new InvalidCredentialsException(ivcX);
		}
	}

	/**
	 * This implementation is necessary if the data source has a connection to VistA but not all of the credentials
	 * @param vistaSession
	 * @param image
	 * @return
	 * @throws UnsupportedOperationException
	 * @throws MethodException
	 * @throws ConnectionException
	 * @throws ImageNotFoundException
	 * @throws ImageNearLineException
	 * @throws IOException
	 */
	private DataSourceInputStream getImageTXTFileInternal(VistaSession vistaSession, Image image)
	throws UnsupportedOperationException, MethodException,
	ConnectionException, ImageNotFoundException, ImageNearLineException, IOException
	{
		boolean gotVistaSession = false;
		try
		{
			ImagingStorageCredentials imagingStorageCredentials = null;
			imagingStorageCredentials = VistaImagingStorageManager.getImagingStorageCredentialsFromCache(image, getSite());
			String serverShare = VistaImagingTranslator.extractServerShare(image);
			if(imagingStorageCredentials == null)
			{
				logger.info("Imaging Storage Credentials for site '" + getSite().getSiteNumber() + "' does not exist in the network location cache, getting from VistA");
				// note that we delay getting the vista session until we are sure we need it
				if(vistaSession == null)
				{
					vistaSession = getVistaSession();
					gotVistaSession = true;
				}
				imagingStorageCredentials = VistaImagingStorageManager.getImagingStorageCredentialsFromVista(vistaSession, serverShare, getSite());
			}
			else
			{
				logger.info("Found Imaging Storage Credentials for share [" + serverShare + "] in the network location cache");
			}

			if(imagingStorageCredentials == null)
				throw new ImageNotFoundException("No Imaging Storage Credentials found for image share [" + serverShare + "] for txt file [" + image.getFullFilename() + "]");
			logger.info("Found Imaging Storage Credentials for network location [" + serverShare + "]");
			return getImageTXTFileInternal(vistaSession, image, imagingStorageCredentials, image.getFullFilename());
		}
		finally
		{
			// if this function is the one that got the connection, return it to the cache here
			if((gotVistaSession) && (vistaSession != null))
			{
				try{vistaSession.close();}
				catch(Throwable t){}
			}
		}
	}

	private DataSourceInputStream getImageTXTFileInternal(VistaSession vistaSession, Image image,
			ImagingStorageCredentials imageNetworkLocation, String imageFilename)
	throws UnsupportedOperationException, MethodException,
	ConnectionException, IOException
	{
		boolean gotVistaSession = false;
		try
		{
			logger.info("About to get HIS updates");
			if(vistaSession == null)
			{
				vistaSession = getVistaSession();
				gotVistaSession = true;
			}

			HashMap<String, String> hisUpdate = getImageHISUpdates(vistaSession, image);
			logger.info("done getting HIS updates");

			DataSourceInputStream txtStream =
				imageConversionUtility.GetTxtStream(imageFilename, imageNetworkLocation, hisUpdate);
			return txtStream;

			//return appendTxtStreamWithHisUpdate(txtStream, hisUpdate);
		}
		finally
		{
			// if this function is the one that got the connection, return it to the cache here
			if((gotVistaSession) && (vistaSession != null))
			{
				try{vistaSession.close();}
				catch(Throwable t){}
			}
		}
	}

}


text:
{-# LANGUAGE DataKinds #-}
-- | Common client monad operations.
module Game.LambdaHack.Client.CommonClient
  ( getPerFid, aidTgtToPos, aidTgtAims, makeLine
  , partAidLeader, partActorLeader, partPronounLeader
  , actorSkillsClient, updateItemSlot, fullAssocsClient, activeItemsClient
  , itemToFullClient, pickWeaponClient, sumOrganEqpClient
  ) where

import Control.Applicative
import Control.Exception.Assert.Sugar
import Control.Monad
import qualified Data.EnumMap.Strict as EM
import Data.Maybe
import Data.Tuple
import qualified NLP.Miniutter.English as MU

import Game.LambdaHack.Client.ItemSlot
import Game.LambdaHack.Client.MonadClient
import Game.LambdaHack.Client.State
import qualified Game.LambdaHack.Common.Ability as Ability
import Game.LambdaHack.Common.Actor
import Game.LambdaHack.Common.ActorState
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.Item
import Game.LambdaHack.Common.ItemStrongest
import qualified Game.LambdaHack.Common.Kind as Kind
import Game.LambdaHack.Common.Level
import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.Msg
import Game.LambdaHack.Common.Perception
import Game.LambdaHack.Common.Point
import Game.LambdaHack.Common.Random
import Game.LambdaHack.Common.Request
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Vector
import qualified Game.LambdaHack.Content.ItemKind as IK

-- | Get the current perception of a client.
getPerFid :: MonadClient m => LevelId -> m Perception
getPerFid lid = do
  fper <- getsClient sfper
  let assFail = assert `failure` "no perception at given level"
                       `twith` (lid, fper)
  return $! EM.findWithDefault assFail lid fper

-- | The part of speech describing the actor or "you" if a leader
-- of the client's faction. The actor may be not present in the dungeon.
partActorLeader :: MonadClient m => ActorId -> Actor -> m MU.Part
partActorLeader aid b = do
  mleader <- getsClient _sleader
  return $! case mleader of
    Just leader | aid == leader -> "you"
    _ -> partActor b

-- | The part of speech with the actor's pronoun or "you" if a leader
-- of the client's faction. The actor may be not present in the dungeon.
partPronounLeader :: MonadClient m => ActorId -> Actor -> m MU.Part
partPronounLeader aid b = do
  mleader <- getsClient _sleader
  return $! case mleader of
    Just leader | aid == leader -> "you"
    _ -> partPronoun b

-- | The part of speech describing the actor (designated by actor id
-- and present in the dungeon) or a special name if a leader
-- of the observer's faction.
partAidLeader :: MonadClient m => ActorId -> m MU.Part
partAidLeader aid = do
  b <- getsState $ getActorBody aid
  partActorLeader aid b

-- | Calculate the position of an actor's target.
aidTgtToPos :: MonadClient m
            => ActorId -> LevelId -> Maybe Target -> m (Maybe Point)
aidTgtToPos aid lidV tgt =
  case tgt of
    Just (TEnemy a _) -> do
      body <- getsState $ getActorBody a
      return $! if blid body == lidV
                then Just (bpos body)
                else Nothing
    Just (TEnemyPos _ lid p _) ->
      return $! if lid == lidV then Just p else Nothing
    Just (TPoint lid p) ->
      return $! if lid == lidV then Just p else Nothing
    Just (TVector v) -> do
      b <- getsState $ getActorBody aid
      Level{lxsize, lysize} <- getLevel lidV
      let shifted = shiftBounded lxsize lysize (bpos b) v
      return $! if shifted == bpos b && v /= Vector 0 0
                then Nothing
                else Just shifted
    Nothing -> do
      scursor <- getsClient scursor
      aidTgtToPos aid lidV $ Just scursor

-- | Check whether one is permitted to aim at a target
-- (this is only checked for actors; positions let player
-- shoot at obstacles, e.g., to destroy them).
-- This assumes @aidTgtToPos@ does not return @Nothing@.
-- Returns a different @seps@, if needed to reach the target actor.
--
-- Note: Perception is not enough for the check,
-- because the target actor can be obscured by a glass wall
-- or be out of sight range, but in weapon range.
aidTgtAims :: MonadClient m
           => ActorId -> LevelId -> Maybe Target -> m (Either Msg Int)
aidTgtAims aid lidV tgt = do
  let findNewEps onlyFirst pos = do
        oldEps <- getsClient seps
        b <- getsState $ getActorBody aid
        mnewEps <- makeLine onlyFirst b pos oldEps
        case mnewEps of
          Just newEps -> return $ Right newEps
          Nothing ->
            return $ Left
                   $ if onlyFirst then "aiming blocked at the first step"
                     else "aiming line to the opponent blocked somewhere"
  case tgt of
    Just (TEnemy a _) -> do
      body <- getsState $ getActorBody a
      let pos = bpos body
      if blid body == lidV
      then findNewEps False pos
      else return $ Left "selected opponent not on this level"
    Just TEnemyPos{} -> return $ Left "selected opponent not visible"
    Just (TPoint lid pos) ->
      if lid == lidV
      then findNewEps True pos
      else return $ Left "selected position not on this level"
    Just (TVector v) -> do
      b <- getsState $ getActorBody aid
      Level{lxsize, lysize} <- getLevel lidV
      let shifted = shiftBounded lxsize lysize (bpos b) v
      if shifted == bpos b && v /= Vector 0 0
      then return $ Left "selected translation is void"
      else findNewEps True shifted
    Nothing -> do
      scursor <- getsClient scursor
      aidTgtAims aid lidV $ Just scursor

-- | Counts the number of steps until the projectile would hit
-- an actor or obstacle. Starts searching with the given eps and returns
-- the first found eps for which the number reaches the distance between
-- actor and target position, or Nothing if none can be found.
makeLine :: MonadClient m => Bool -> Actor -> Point -> Int -> m (Maybe Int)
makeLine onlyFirst body fpos epsOld = do
  cops@Kind.COps{cotile=Kind.Ops{ouniqGroup}} <- getsState scops
  lvl@Level{lxsize, lysize} <- getLevel (blid body)
  bs <- getsState $ filter (not . bproj)
                    . actorList (const True) (blid body)
  let unknownId = ouniqGroup "unknown space"
      dist = chessDist (bpos body) fpos
      calcScore eps = case bla lxsize lysize eps (bpos body) fpos of
        Just bl ->
          let blDist = take dist bl
              blZip = zip (bpos body : blDist) blDist
              noActor p = all ((/= p) . bpos) bs || p == fpos
              accessU = all noActor blDist
                        && all (uncurry $ accessibleUnknown cops lvl) blZip
              accessFirst | not onlyFirst = False
                          | otherwise =
                all noActor (take 1 blDist)
                && all (uncurry $ accessibleUnknown cops lvl) (take 1 blZip)
              nUnknown = length $ filter ((== unknownId) . (lvl `at`)) blDist
          in if accessU then - nUnknown
             else if accessFirst then -10000
             else minBound
        Nothing -> assert `failure` (body, fpos, epsOld)
      tryLines curEps (acc, _) | curEps == epsOld + dist = acc
      tryLines curEps (acc, bestScore) =
        let curScore = calcScore curEps
            newAcc = if curScore > bestScore
                     then (Just curEps, curScore)
                     else (acc, bestScore)
        in tryLines (curEps + 1) newAcc
  return $! if dist <= 0 then Nothing  -- ProjectAimOnself
            else if calcScore epsOld > minBound then Just epsOld  -- keep old
            else tryLines (epsOld + 1) (Nothing, minBound)  -- generate best

actorSkillsClient :: MonadClient m => ActorId -> m Ability.Skills
actorSkillsClient aid = do
  activeItems <- activeItemsClient aid
  body <- getsState $ getActorBody aid
  fact <- getsState $ (EM.! bfid body) . sfactionD
  side <- getsClient sside
  -- Newest Leader in _sleader, not yet in sfactionD.
  mleader1 <- if side == bfid body then getsClient _sleader else return Nothing
  let mleader2 = fst <$> gleader fact
      mleader = mleader1 `mplus` mleader2
  getsState $ actorSkills mleader aid activeItems

updateItemSlot :: MonadClient m
               => CStore -> Maybe ActorId -> ItemId -> m SlotChar
updateItemSlot store maid iid = do
  slots@(itemSlots, organSlots) <- getsClient sslots
  let onlyOrgans = store == COrgan
      lSlots = if onlyOrgans then organSlots else itemSlots
      incrementPrefix m l iid2 = EM.insert l iid2 $
        case EM.lookup l m of
          Nothing -> m
          Just iidOld ->
            let lNew = SlotChar (slotPrefix l + 1) (slotChar l)
            in incrementPrefix m lNew iidOld
  case lookup iid $ map swap $ EM.assocs lSlots of
    Nothing -> do
      side <- getsClient sside
      item <- getsState $ getItemBody iid
      lastSlot <- getsClient slastSlot
      mb <- maybe (return Nothing) (fmap Just . getsState . getActorBody) maid
      l <- getsState $ assignSlot store item side mb slots lastSlot
      let newSlots | onlyOrgans = ( itemSlots
                                  , incrementPrefix organSlots l iid )
                   | otherwise =  ( incrementPrefix itemSlots l iid
                                  , organSlots )
      modifyClient $ \cli -> cli {sslots = newSlots}
      return l
    Just l -> return l  -- slot already assigned; a letter or a number

fullAssocsClient :: MonadClient m
                 => ActorId -> [CStore] -> m [(ItemId, ItemFull)]
fullAssocsClient aid cstores = do
  cops <- getsState scops
  discoKind <- getsClient sdiscoKind
  discoEffect <- getsClient sdiscoEffect
  getsState $ fullAssocs cops discoKind discoEffect aid cstores

activeItemsClient :: MonadClient m => ActorId -> m [ItemFull]
activeItemsClient aid = do
  activeAssocs <- fullAssocsClient aid [CEqp, COrgan]
  return $! map snd activeAssocs

itemToFullClient :: MonadClient m => m (ItemId -> ItemQuant -> ItemFull)
itemToFullClient = do
  cops <- getsState scops
  discoKind <- getsClient sdiscoKind
  discoEffect <- getsClient sdiscoEffect
  s <- getState
  let itemToF iid = itemToFull cops discoKind discoEffect iid
                               (getItemBody iid s)
  return itemToF

-- Client has to choose the weapon based on its partial knowledge,
-- because if server chose it, it would leak item discovery information.
pickWeaponClient :: MonadClient m
                 => ActorId -> ActorId
                 -> m (Maybe (RequestTimed 'Ability.AbMelee))
pickWeaponClient source target = do
  eqpAssocs <- fullAssocsClient source [CEqp]
  bodyAssocs <- fullAssocsClient source [COrgan]
  actorSk <- actorSkillsClient source
  sb <- getsState $ getActorBody source
  localTime <- getsState $ getLocalTime (blid sb)
  let allAssocs = eqpAssocs ++ bodyAssocs
      calm10 = calmEnough10 sb $ map snd allAssocs
      forced = assert (not $ bproj sb) False
      permitted = permittedPrecious calm10 forced
      preferredPrecious = either (const False) id . permitted
      strongest = strongestMelee True localTime allAssocs
      strongestPreferred = filter (preferredPrecious . snd . snd) strongest
  case strongestPreferred of
    _ | EM.findWithDefault 0 Ability.AbMelee actorSk <= 0 -> return Nothing
    [] -> return Nothing
    iis@((maxS, _) : _) -> do
      let maxIis = map snd $ takeWhile ((== maxS) . fst) iis
      (iid, _) <- rndToAction $ oneOf maxIis
      -- Prefer COrgan, to hint to the player to trash the equivalent CEqp item.
      let cstore = if isJust (lookup iid bodyAssocs) then COrgan else CEqp
      return $ Just $ ReqMelee target iid cstore

sumOrganEqpClient :: MonadClient m
                  => IK.EqpSlot -> ActorId -> m Int
sumOrganEqpClient eqpSlot aid = do
  activeItems <- activeItemsClient aid
  return $! sumSlotNoFilter eqpSlot activeItems


text:
import json
from urllib import urlopen
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.models import SocialAccount, SocialToken, SocialApp, SocialLogin
from django.contrib.auth import authenticate, login, logout
from django.core.urlresolvers import reverse

# view imports
from django.views.generic import DetailView
from django.views.generic import RedirectView
from django.views.generic import UpdateView
from django.views.generic import ListView

# Only authenticated users can access views using this.
from braces.views import LoginRequiredMixin

# Import the form from users/forms.py
from rest_framework import viewsets, permissions, status, views
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from profiles.models import UserProfile, Profile, Threat
from permissions import IsAccountOwner
from serializers import UserSerializer
from .forms import UserForm

# Import the customized User model
from .models import User

class UserDetailView(LoginRequiredMixin, DetailView):
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

class UserRedirectView(LoginRequiredMixin, RedirectView):
    permanent = False

    def get_redirect_url(self):
        return reverse("users:detail",
                       kwargs={"username": self.request.user.username})

class UserUpdateView(LoginRequiredMixin, UpdateView):
    form_class = UserForm

    # we already imported User in the view code above, remember?
    model = User

    # send the user back to their own page after a successful update
    def get_success_url(self):
        return reverse("users:detail",
                       kwargs={"username": self.request.user.username})

    def get_object(self):
        # Only get the User record for the user making the request
        return User.objects.get(username=self.request.user.username)

class UserListView(LoginRequiredMixin, ListView):
    model = User
    # These next two lines tell the view to index lookups by username
    slug_field = "username"
    slug_url_kwarg = "username"

# ViewSets define the view behavior.
class UserViewSet(viewsets.ViewSet):
    permission_classes = (IsAuthenticatedOrReadOnly,)

    def list(self, request):
        if request.user.is_authenticated():
            queryset = User.objects.get(username=request.user)
            serializer = UserSerializer(queryset, context={'request': request})
            return Response(serializer.data)
        else:
            return Response()

'''
    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            user = User.objects.create_user(**serializer.validated_data)
            userProfile = UserProfile.objects.create(user=user)
            for threat in Threat.objects.all():
                Profile.objects.create(userProfile=userProfile, threat=threat, value=5)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
        return Response({
            'status': 'Bad request',
            'message': 'Account could not be created with received data.'
        }, status=status.HTTP_400_BAD_REQUEST)

class LoginView(views.APIView):
    permission_classes = []

    def get(self, request, format=None):
        content = {
            'user': unicode(request.user),  # `django.contrib.auth.User` instance.
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

    def post(self, request, format=None):
        data = json.loads(request.body)

        email = data.get('email', None)
        password = data.get('password', None)

        user = authenticate(username=email, password=password)

        if user is not None:
            if user.is_active:
                print("User is valid, active and authenticated")
                login(request, user)
                serialized = UserSerializer(user, context={'request': request})

                return Response(serialized.data)
            else:
                print("The password is valid, but the account has been disabled!")
                return Response({
                    'status': 'Unauthorized',
                    'message': 'This account has been disabled.'
                }, status=status.HTTP_401_UNAUTHORIZED)
        else:
            # the authentication system was unable to verify the username and password
            print("The username and password were incorrect.")
            return Response({
                'status': 'Unauthorized',
                'message': 'Username/password combination invalid.'
            }, status=status.HTTP_401_UNAUTHORIZED)

class LoginTokenView(views.APIView):
    permission_classes = []

    def post(self, request, format=None):
        data = json.loads(request.body)
        access_token = data.get('access_token', None)

        url = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token="+access_token
        google_data = json.loads(str(urlopen(url).read()))

        if google_data['issued_to']:
            email = google_data.get('email', None)
            uid = google_data.get('user_id', None)
            userExists = User.objects.filter(username=email).count()
            print 'userExists ----->'
            print userExists
            if userExists > 0:
                user = User.objects.get(username=email)
                user.backend = "allauth.account.auth_backends.AuthenticationBackend"
                login(request, user)
                serialized = UserSerializer(user, context={'request': request})
                print('user authenticated?')
                print(user.is_authenticated())
                return Response(serialized.data)
            else:
                user = User.objects.create_user(username=email, email=email, password=None)
                user.backend = "allauth.account.auth_backends.AuthenticationBackend"
                user.save()
                userProfile = UserProfile.objects.create(user=user)
                for threat in Threat.objects.all():
                    Profile.objects.create(userProfile=userProfile, threat=threat, value=5)
                sa = SocialAccount.objects.create(user=user, provider='google', uid=uid, extra_data=google_data)
                sa.save()
                token = SocialToken.objects.create(app=SocialApp.objects.get(provider='google'), account=sa, token=access_token)
                token.save()
                login(request, user)
                serialized = UserSerializer(user, context={'request': request})
                return Response(serialized.data)
        elif google_data['error']:
            return Response({
                'status': 'Unauthorized',
                'message': 'Invalid Google access token.'
            }, status=status.HTTP_401_UNAUTHORIZED)

class LogoutView(views.APIView):
    permission_classes = []

    def post(self, request, format=None):
        logout(request)

        return Response({}, status=status.HTTP_204_NO_CONTENT)
'''


text:
import { IWrappedMetaProps, ObjectField, meta } from '../../../../lib';
import { SimpleField } from './SimpleField';
import { observable } from 'mobx';
import * as React from 'react';
import { Button, Col, Grid, Row } from 'react-bootstrap';

class Field extends React.Component<IWrappedMetaProps, {}> {
  private id = 0;
  private arrayFields = observable<number>([]);

  public render() {
    const fields = this.arrayFields.map(f => {
      return (
        <Row key={f}>
          <ObjectField>
            <Col xs={8}>
              <SimpleField name='arrayField' type='text' />
            </Col>
            <Col xs={4} style={{ marginTop: '1.8em' }}>
              <Button onClick={() => this.arrayFields.remove(f)}>Remove</Button>
            </Col>
          </ObjectField>
        </Row>
      );
    });

    return (
      <Grid>
        {fields}
        <Button onClick={() => this.arrayFields.push(this.id++)}>Add Another</Button>
      </Grid>
    );
  }
}

export const CustomArrayField = meta(Field);


text:
from uai.api.base_api import BaseUaiServiceApiOp

class CreateUAIExclusiveServiceApiOp(BaseUaiServiceApiOp):

    ACTION_NAME = "CreateUAIExclusiveService"

    def __init__(self, public_key, private_key, srv_name, bill_prod, business_group='',project_id='', region='', zone=''):
        super(CreateUAIExclusiveServiceApiOp, self).__init__(self.ACTION_NAME, public_key, private_key, project_id, region, zone )
        self.cmd_params['Region'] = region if region != '' else super(CreateUAIExclusiveServiceApiOp, self).PARAMS_DEFAULT_REGION
        self.cmd_params['SrvName'] = srv_name
        self.cmd_params['BillProdId'] = bill_prod
        self.cmd_params['BusinessGroup'] = business_group if business_group != '' else self.PARAMS_DEFAULT_BUSINESSGROUP

    def _check_args(self, params):
        if params['SrvName'] == '':
            return False
        if params['BillProdId'] == '':
            return False
        return True

    def call_api(self):
        succ, self.rsp = super(CreateUAIExclusiveServiceApiOp, self).call_api()
        return succ, self.rsp


text:
package sdb

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"github.com/crowdmob/goamz/aws"
	"net/http"
	"net/url"
	"sort"
	"strings"
)

var b64 = base64.StdEncoding

// ----------------------------------------------------------------------------
// SimpleDB signing (http://goo.gl/CaY81)

func sign(auth aws.Auth, method, path string, params url.Values, headers http.Header) {
	var host string
	for k, v := range headers {
		k = strings.ToLower(k)
		switch k {
		case "host":
			host = v[0]
		}
	}

	// set up some defaults used for signing the request
	params["AWSAccessKeyId"] = []string{auth.AccessKey}
	params["SignatureVersion"] = []string{"2"}
	params["SignatureMethod"] = []string{"HmacSHA256"}
	if auth.Token() != "" {
		params["SecurityToken"] = []string{auth.Token()}
	}

	// join up all the incoming params
	var sarray []string
	for k, v := range params {
		sarray = append(sarray, aws.Encode(k)+"="+aws.Encode(v[0]))
	}
	sort.StringSlice(sarray).Sort()
	joined := strings.Join(sarray, "&")

	// create the payload, sign it and create the signature
	payload := strings.Join([]string{method, host, "/", joined}, "\n")
	hash := hmac.New(sha256.New, []byte(auth.SecretKey))
	hash.Write([]byte(payload))
	signature := make([]byte, b64.EncodedLen(hash.Size()))
	b64.Encode(signature, hash.Sum(nil))

	// add the signature to the outgoing params
	params["Signature"] = []string{string(signature)}
}


text:
cask "switchkey" do
  version "1.1.3"
  sha256 "a8a62231adddffc954a894b7fd00051d903de31a0e37d68787425bdc287399c8"

  url "https://github.com/itsuhane/SwitchKey/releases/download/v#{version}/SwitchKey.zip"
  appcast "https://github.com/itsuhane/SwitchKey/releases.atom"
  name "SwitchKey"
  homepage "https://github.com/itsuhane/SwitchKey"

  app "SwitchKey.app"

  zap trash: "~/Library/Preferences/itsuhane.tools.SwitchKey.plist"
end