text:
package com.pacoapp.paco.model;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.type.TypeReference;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.pacoapp.paco.PacoConstants;
import com.pacoapp.paco.UserPreferences;
import com.pacoapp.paco.shared.model2.ActionTrigger;
import com.pacoapp.paco.shared.model2.EventInterface;
import com.pacoapp.paco.shared.model2.EventStore;
import com.pacoapp.paco.shared.model2.ExperimentDAO;
import com.pacoapp.paco.shared.model2.ExperimentGroup;
import com.pacoapp.paco.shared.model2.ExperimentValidator;
import com.pacoapp.paco.shared.model2.Input2;
import com.pacoapp.paco.shared.model2.InterruptCue;
import com.pacoapp.paco.shared.model2.JsonConverter;
import com.pacoapp.paco.shared.model2.PacoAction;
import com.pacoapp.paco.shared.model2.PacoNotificationAction;
import com.pacoapp.paco.shared.model2.Schedule;
import com.pacoapp.paco.shared.model2.ScheduleTrigger;
import com.pacoapp.paco.shared.model2.ValidationMessage;
import com.pacoapp.paco.shared.scheduling.ActionScheduleGenerator;
import com.pacoapp.paco.shared.util.TimeUtil;

public class ExperimentProviderUtil implements EventStore {

  private Context context;
  private ContentResolver contentResolver;
  public static final String AUTHORITY = "com.google.android.apps.paco.ExperimentProvider";
  private static final String PUBLIC_EXPERIMENTS_FILENAME = "experiments";
  private static final String MY_EXPERIMENTS_FILENAME = "my_experiments";

  DateTimeFormatter endDateFormatter = DateTimeFormat.forPattern(TimeUtil.DATE_FORMAT);

  public ExperimentProviderUtil(Context context) {
    super();
    this.context = context;
    if (context == null) {
      throw new IllegalArgumentException("Need a context to instantiate experimentproviderutil");
    }
    this.contentResolver = context.getContentResolver();
  }

  public List<Experiment> getJoinedExperiments() {
    List<Experiment> cachedExperiments = JoinedExperimentCache.getInstance().getExperiments();
    if (cachedExperiments.size() > 0) {
      return cachedExperiments;
    }

    final List<Experiment> foundExperiments = findExperimentsBy(null, ExperimentColumns.JOINED_EXPERIMENTS_CONTENT_URI);
    if (foundExperiments != null && foundExperiments.size() > 0 ) {
      JoinedExperimentCache.getInstance().insertExperiments(foundExperiments);
    }
    return foundExperiments;
  }

  public List<Long> getJoinedExperimentServerIds() {
    List<Experiment> joinedExperiments = getJoinedExperiments();

    List<Experiment> stillRunningExperiments = Lists.newArrayList();
    DateMidnight tonightMidnight = new DateMidnight().plusDays(1);
    DateTime now = DateTime.now();
    for (Experiment experiment : joinedExperiments) {

      final ExperimentDAO experimentDAO = experiment.getExperimentDAO();
      if (experimentDAO != null && !ActionScheduleGenerator.isOver(now, experimentDAO)) {
        stillRunningExperiments.add(experiment);
      }
    }
    List<Long> experimentIds = Lists.transform(stillRunningExperiments, new Function<Experiment, Long>() {
      public Long apply(Experiment experiment) {
        return experiment.getServerId();
      }
    });
    return experimentIds;
  }

  private boolean isJoinedExperimentAndroidId(long id) {
    String select = ExperimentColumns._ID + "=" + id;
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(ExperimentColumns.CONTENT_URI,
          null, select, null, null);
      if (cursor != null && cursor.moveToNext()) {
        return true;
      }
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return false;
  }

  public List<Experiment> getExperimentsByServerId(long id) {
    List<Experiment> cachedExperiments = JoinedExperimentCache.getInstance().getExperimentsByServerId(id);
    if (cachedExperiments.size() > 0) {
      return cachedExperiments;
    }
    String select = ExperimentColumns.SERVER_ID + "=" + id;
    final List<Experiment> foundExperiments = findExperimentsBy(select, ExperimentColumns.CONTENT_URI);

    if (foundExperiments != null && foundExperiments.size() > 0) {
      JoinedExperimentCache.getInstance().insertExperiments(foundExperiments);
    }

    return foundExperiments;
  }

  public Experiment getExperimentByServerId(long id) {
    Experiment cachedExperiment = JoinedExperimentCache.getInstance().getExperimentByServerId(id);
    if (cachedExperiment != null) {
      return cachedExperiment;
    }

    String select = ExperimentColumns.SERVER_ID + "=" + id;
    final Experiment foundExperiment = findExperimentBy(select, ExperimentColumns.CONTENT_URI);

    if (foundExperiment != null) {
      JoinedExperimentCache.getInstance().insertExperiment(foundExperiment);
    }

    return foundExperiment;
  }

  private Uri insertExperiment(Experiment experiment) {
    final Uri returnedUri = contentResolver.insert(ExperimentColumns.CONTENT_URI,
        createContentValues(experiment));
    long rowId = Long.parseLong(returnedUri.getLastPathSegment());
    experiment.setId(rowId);

    JoinedExperimentCache.getInstance().insertExperiment(experiment);
    return returnedUri;
  }

  /**
   * This operation takes a default experiment from the server,
   * and clones it to created an experiment record that represents
   * an experiment the user has joined. This ensures that even if the
   * experiment is no longer available on the server, or is updated for
   * future users, it remains the same for this user by default.
   * Future work could ask them if they want to upgrade their
   * joined experiment to a new version of the experiment on the
   * server, but that is out of scope for now.
   * @param experiment
   * @return
   */
  public Uri insertFullJoinedExperiment(Experiment experiment) {
    setJoinDateOnSchedules(experiment);
    return insertExperiment(experiment);
  }

  private void setJoinDateOnSchedules(Experiment experiment) {
    long joinDateMillis = getJoinDateMillis(experiment);
    for (ExperimentGroup experimentGroup : experiment.getExperimentDAO().getGroups()) {
      List<ActionTrigger> actionTriggers = experimentGroup.getActionTriggers();
      for (ActionTrigger actionTrigger : actionTriggers) {
        if (actionTrigger instanceof ScheduleTrigger) {
          ScheduleTrigger scheduleTrigger = (ScheduleTrigger)actionTrigger;
          List<Schedule> schedules = scheduleTrigger.getSchedules();
          for (Schedule schedule : schedules) {
            schedule.setJoinDateMillis(joinDateMillis);
          }
        }
      }
    }
  }

  private Long getJoinDateMillis(Experiment experiment) {
    return TimeUtil.unformatDateWithZone(experiment.getJoinDate()).getMillis();
  }

  // For testing
  public Uri insertFullJoinedExperiment(String contentAsString) throws JsonParseException, JsonMappingException, IOException {
    Experiment experiment = getSingleExperimentFromJson(contentAsString);
    experiment.setJoinDate(TimeUtil.formatDateWithZone(new DateTime()));
    return insertFullJoinedExperiment(experiment);
  }

  /**
   * This uses the Android ContentProvider id for the joined experiment
   * @param experimentId
   */
  public void deleteExperiment(long experimentId) {
    if (isJoinedExperimentAndroidId(experimentId)) {
      String[] selectionArgs = new String[] {Long.toString(experimentId)};
      contentResolver.delete(ExperimentColumns.CONTENT_URI,
          "_id = ?",
          selectionArgs);
      JoinedExperimentCache.getInstance().deleteExperiment(experimentId);
    }
  }

  /**
   * This is used by refresh downloaders only
   *
   * @param contentAsString
   * @throws JsonParseException
   * @throws JsonMappingException
   * @throws IOException
   */
  public void updateExistingExperiments(String contentAsString) throws JsonParseException, JsonMappingException, IOException {
    Map<String, Object> results = fromEntitiesJson(contentAsString);
    List<Experiment> experimentList = (List<Experiment>) results.get("results");
    updateExistingExperiments(experimentList, false);
  }

  /**
   * Used when refreshing experiment list from the server.
   * If the experiment server id is already in the database,
   * then update it, otherwise, add it.
   * @param experimentList
   * @param shouldOverrideExistingSettings downloaded (refreshed experiments should not override certain
   * local properties. Locally modified experiments should override local properties, e.g., logActions.
   */
  public void updateExistingExperiments(List<Experiment> newExperimentDefinitions,
                                        Boolean shouldOverrideExistingSettings) {
    for (Experiment experiment : newExperimentDefinitions) {
      List<Experiment> existingList = getExperimentsByServerId(experiment.getServerId());
      if (existingList.size() == 0) {
        continue;
      }
      for (Experiment existingExperiment : existingList) { // should become only 1 element if we prevent joining experiments multiple times
        copyAllPropertiesToExistingJoinedExperiment(experiment, existingExperiment, shouldOverrideExistingSettings);
        updateJoinedExperiment(existingExperiment);
      }

    }
  }

  private void copyAllPropertiesToExistingJoinedExperiment(Experiment newExperiment, Experiment existingExperiment,
                                                           Boolean shouldOverrideExistingSettings) {
    UserPreferences userPrefs = new UserPreferences(context);
    if (shouldOverrideExistingSettings || !userPrefs.experimentEdited(existingExperiment.getId())) {
      ExperimentDAO newExperimentDAO = newExperiment.getExperimentDAO();
      ExperimentDAO existingDAO = existingExperiment.getExperimentDAO();
      // TODO preserve any modified schedule settings if it is user-editable and different from the new

      existingExperiment.setExperimentDAO(newExperimentDAO);
    }

  }

  public void updateJoinedExperiment(Experiment experiment) {
    long t1 = System.currentTimeMillis();
    int count = contentResolver.update(ExperimentColumns.JOINED_EXPERIMENTS_CONTENT_URI,
        createContentValues(experiment),
        ExperimentColumns._ID + "=" + experiment.getId(), null);
    JoinedExperimentCache.getInstance().insertExperiment(experiment);
    Log.i(ExperimentProviderUtil.class.getSimpleName(), " updated "+ count + " rows. Time: " + (System.currentTimeMillis() - t1));
  }

  public void deleteAllExperiments() {
    contentResolver.delete(ExperimentColumns.JOINED_EXPERIMENTS_CONTENT_URI, null, null);
    JoinedExperimentCache.getInstance().deleteAllExperiments();
  }

  private Experiment findExperimentBy(String select, Uri contentUri) {
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(contentUri,
          null, select, null, null);
      if (cursor != null && cursor.moveToNext()) {
        Experiment experiment = createExperiment(cursor);
        return experiment;
      }
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return null;
  }

  private List<Experiment> findExperimentsBy(String select, Uri contentUri) {
    List<Experiment> experiments = new ArrayList<Experiment>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(contentUri,
          null, select, null, null);
      if (cursor != null) {
        while (cursor.moveToNext()) {
         Experiment experiment = createExperiment(cursor);
         experiments.add(experiment);
        }
      }
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return experiments;
  }

  /** This converts the old version of json (db == 22) to the new model
   *
   * @param experimentDAO
   * @param jsonOfExperiment
   * @throws JsonProcessingException
   * @throws IOException
   */
  public static void copyAllPropertiesFromJsonToExperimentDAO(ExperimentDAO experimentDAO, String jsonOfExperiment) throws JsonProcessingException, IOException {
    ObjectMapper mapper = JsonConverter.getObjectMapper();
    JsonNode rootNode = mapper.readTree(jsonOfExperiment);
    if (rootNode.has("id")) {
      experimentDAO.setId(rootNode.path("id").getLongValue());
    }
    if (rootNode.has("title")) {
      experimentDAO.setTitle(rootNode.path("title").getTextValue());
    }
    if (rootNode.has("description")) {
      experimentDAO.setCreator(rootNode.path("description").getTextValue());
    }
    if (rootNode.has("creator")) {
      experimentDAO.setCreator(rootNode.path("creator").getTextValue());
      experimentDAO.setContactEmail(rootNode.path("creator").getTextValue());
    }
    if (rootNode.has("contactEmail")) {
      experimentDAO.setContactEmail(rootNode.path("contactEmail").getTextValue());
    }
    if (!rootNode.has("creator") && !rootNode.has("contactEmail")) {
      experimentDAO.setContactEmail(rootNode.path("").getTextValue());
    }
    if (rootNode.has("modifyDate")) {
      experimentDAO.setModifyDate(rootNode.path("modifyDate").getTextValue());
    }
    if (rootNode.has("version")) {
      experimentDAO.setVersion(rootNode.path("version").getIntValue());
    }
    if (rootNode.has("joinDate")) {
      experimentDAO.setJoinDate(rootNode.path("joinDate").getTextValue());
    }
    if (rootNode.has("informedConsentForm")) {
      experimentDAO.setInformedConsentForm(rootNode.path("informedConsent").getTextValue());
    }
    if (rootNode.has("recordPhoneDetails")) {
      experimentDAO.setRecordPhoneDetails(rootNode.path("recordPhoneDetails").getBooleanValue());
    }
    if (rootNode.has("deleted")) {
      experimentDAO.setDeleted(rootNode.path("deleted").getBooleanValue());
    }
    if (rootNode.has("extraDataCollectionDeclarations")) {
      List<Integer> edcd = Lists.newArrayList();
      List<JsonNode> edcdNodes = rootNode.findValues("extraDataCollectionDeclarations");
      for (JsonNode edcdNode : edcdNodes) {
        edcd.add(edcdNode.getIntValue());
      }
      experimentDAO.setExtraDataCollectionDeclarations(edcd);
    }

    List<String> admins = Lists.newArrayList();
    List<JsonNode> adminNodes = rootNode.findValues("admins");
    for (JsonNode adminNode : adminNodes) {
      admins.add(adminNode.getTextValue());
    }
    experimentDAO.setAdmins(admins);

    if (rootNode.has("published")) {
      experimentDAO.setPublished(rootNode.path("published").getBooleanValue());
    }
    List<String> publishedList = Lists.newArrayList();
    List<JsonNode> publishedListNodes = rootNode.findValues("publishedUsers");
    for (JsonNode publishedListNode : publishedListNodes) {
      publishedList.add(publishedListNode.getTextValue());
    }
    experimentDAO.setPublishedUsers(publishedList);

    ExperimentGroup defaultExperimentGroup = new ExperimentGroup();
    defaultExperimentGroup.setName("default");
    experimentDAO.getGroups().add(defaultExperimentGroup);

    if (rootNode.has("endDate")) {
      defaultExperimentGroup.setEndDate(rootNode.path("endDate").getTextValue());
    }
    if (rootNode.has("startDate")) {
      defaultExperimentGroup.setEndDate(rootNode.path("startDate").getTextValue());
    }
    if (rootNode.has("fixedDuration")) {
      defaultExperimentGroup.setFixedDuration(rootNode.path("fixedDuration").getBooleanValue());
    }

//    experimentDAO.setWebRecommended(experiment.isWebRecommended());
    // maybe blow up on webrecommended to let them know to unjoin and rejoin
    // TODO figure out how to handle this.

    if (rootNode.has("customRendering")) {
      defaultExperimentGroup.setCustomRendering(rootNode.path("customRendering").getBooleanValue());
    }
    if (rootNode.has("customRenderingCode")) {
      defaultExperimentGroup.setCustomRenderingCode(rootNode.path("customRenderingCode").getTextValue());
    }

    if (rootNode.has("feedbackType")) {
      //see feedback section below
      defaultExperimentGroup.setFeedbackType(rootNode.path("feedbackType").getIntValue());
    }
    if (rootNode.has("logActions")) {
      defaultExperimentGroup.setLogActions(rootNode.path("logActions").getBooleanValue());
    }

    if (rootNode.has("backgroundListen")) {
      defaultExperimentGroup.setBackgroundListen(rootNode.path("backgroundListen").getBooleanValue());
    }
    if (rootNode.has("backgroundListenSourceIdentifier")) {
      defaultExperimentGroup.setBackgroundListenSourceIdentifier(rootNode.path("backgroundListenSourceIdentifier").getTextValue());
    }
    if (rootNode.has("inputs")) {
      List<Input2> inputs = Lists.newArrayList();
      ArrayNode inputsNode = (ArrayNode)rootNode.path("inputs");

      for (int i=0; i < inputsNode.size(); i++) {
        JsonNode inputNode = inputsNode.get(i);
        Input2 input = new Input2();
        inputs.add(input);
        if (inputNode.has("name")) {
          input.setName(inputNode.path("name").getTextValue());
        }
        if (inputNode.has("required")) {
          input.setRequired(inputNode.path("required").getBooleanValue());
        }
        if (inputNode.has("mandatory")) {
          input.setRequired(inputNode.path("mandatory").getBooleanValue());
        }
        if (inputNode.has("conditional")) {
          input.setConditional(inputNode.path("conditional").getBooleanValue());
        }
        if (inputNode.has("conditionExpression")) {
          input.setConditionExpression(inputNode.path("conditionExpression").getTextValue());
        }
        if (inputNode.has("responseType")) {
          input.setResponseType(inputNode.path("responseType").getTextValue());
        }
        if (inputNode.has("text")) {
          input.setText(inputNode.path("text").getTextValue());
        }
        if (inputNode.has("likertSteps")) {
          input.setLikertSteps(inputNode.path("likertSteps").getIntValue());
        }
        if (inputNode.has("leftSideLabel")) {
          input.setLeftSideLabel(inputNode.path("leftSideLabel").getTextValue());
        }
        if (inputNode.has("rightSideLabel")) {
          input.setRightSideLabel(inputNode.path("rightSideLabel").getTextValue());
        }
        if (inputNode.has("multiselect")) {
          input.setMultiselect(inputNode.path("multiselect").getBooleanValue());
        }
        List<String> listChoices = Lists.newArrayList();
        ArrayNode listChoicesNode = (ArrayNode) inputNode.path("listChoices");
        for (int l = 0; l < listChoicesNode.size(); l++) {
          JsonNode listChoiceNode = listChoicesNode.get(l);
          listChoices.add(listChoiceNode.getTextValue());
        }

        input.setListChoices(listChoices);
      }

      defaultExperimentGroup.setInputs(inputs);
    }

    //signaling mechanisms
    if (rootNode.has("signalingMechanisms")) {
      List<ActionTrigger> actionTriggers = defaultExperimentGroup.getActionTriggers();
      ArrayNode signalingMechanismNodes = (ArrayNode) rootNode.path("signalingMechanisms");
      for (int k = 0; k< signalingMechanismNodes.size(); k++) {
        JsonNode signalingMechanismNode = signalingMechanismNodes.get(k);
          if (signalingMechanismNode.has("type")) {
          String type = signalingMechanismNode.path("type").getTextValue();

          PacoNotificationAction defaultAction = new PacoNotificationAction();
          defaultAction.setActionCode(PacoAction.NOTIFICATION_TO_PARTICIPATE_ACTION_CODE);
          defaultAction.setId(1l);

          if (type.equals("signalSchedule")) {
            com.pacoapp.paco.shared.model2.ScheduleTrigger trigger = new com.pacoapp.paco.shared.model2.ScheduleTrigger();
            trigger.setId(1l);
            trigger.getActions().add(defaultAction);
            com.pacoapp.paco.shared.model2.Schedule schedule = new com.pacoapp.paco.shared.model2.Schedule();
            schedule.setId(1l);
            defaultAction.setSnoozeCount(signalingMechanismNode.path("snoozeCount").getIntValue());
            defaultAction.setSnoozeTime(signalingMechanismNode.path("snoozeTime").getIntValue());
            defaultAction.setTimeout(signalingMechanismNode.path("timeout").getIntValue());

            schedule.setScheduleType(signalingMechanismNode.path("scheduleType").getIntValue());
            schedule.setEsmFrequency(signalingMechanismNode.path("esmFrequency").getIntValue());
            schedule.setEsmPeriodInDays(signalingMechanismNode.path("esmPeriodInDays").getIntValue());
            schedule.setEsmStartHour(signalingMechanismNode.path("esmStartHour").getLongValue());
            schedule.setEsmEndHour(signalingMechanismNode.path("esmEndHour").getLongValue());
            schedule.setRepeatRate(signalingMechanismNode.path("repeatRate").getIntValue());
            schedule.setWeekDaysScheduled(signalingMechanismNode.path("weekdaysScheduled").getIntValue());
            schedule.setNthOfMonth(signalingMechanismNode.path("nthOfMonth").getIntValue());
            schedule.setByDayOfMonth(signalingMechanismNode.path("byDayOfMonth").getBooleanValue());
            schedule.setDayOfMonth(signalingMechanismNode.path("dayOfMonth").getIntValue());
            schedule.setEsmWeekends(signalingMechanismNode.path("esmWeekends").getBooleanValue());
            schedule.setMinimumBuffer(signalingMechanismNode.path("minimumBuffer").getIntValue());

            schedule.setUserEditable(signalingMechanismNode.path("userEditable").getBooleanValue());
            schedule.setOnlyEditableOnJoin(signalingMechanismNode.path("onlyEditableOnJoin").getBooleanValue());

            List<com.pacoapp.paco.shared.model2.SignalTime> signalTimes = schedule.getSignalTimes();
            if (signalingMechanismNode.has("signalTimes")) {
              ArrayNode signalTimeNodes = (ArrayNode) signalingMechanismNode.path("signalTimes");
              for (int l = 0; l < signalTimeNodes.size(); l++) {
                JsonNode signalTimeNode  = signalTimeNodes.get(l);
                com.pacoapp.paco.shared.model2.SignalTime newSt = new com.pacoapp.paco.shared.model2.SignalTime();
                newSt.setType(signalTimeNode.path("type").getIntValue());
                newSt.setFixedTimeMillisFromMidnight(signalTimeNode.path("fixedTimeMillisFromMidnight").getIntValue());
                newSt.setBasis(signalTimeNode.path("basis").getIntValue());
                newSt.setOffsetTimeMillis(signalTimeNode.path("offsetTimeMillis").getIntValue());
                newSt.setLabel(signalTimeNode.path("label").getTextValue());
                newSt.setMissedBasisBehavior(signalTimeNode.path("missedBasisBehavior").getIntValue());
                schedule.getSignalTimes().add(newSt);
              }
            }

            trigger.getSchedules().add(schedule);
            actionTriggers.add(trigger);
          } else if (type.equals("trigger")) {
            com.pacoapp.paco.shared.model2.InterruptTrigger trigger = new com.pacoapp.paco.shared.model2.InterruptTrigger();
            trigger.setId(1l);
            trigger.getActions().add(defaultAction);

            defaultAction.setSnoozeCount(signalingMechanismNode.path("snoozeCount").getIntValue());
            defaultAction.setSnoozeTime(signalingMechanismNode.path("snoozeTime").getIntValue());
            defaultAction.setTimeout(signalingMechanismNode.path("timeout").getIntValue());

            trigger.setMinimumBuffer(signalingMechanismNode.path("minimumBuffer").getIntValue());
            InterruptCue cue = new InterruptCue();
            if (signalingMechanismNode.has("eventCode")) {
              cue.setCueCode(signalingMechanismNode.path("eventCode").getIntValue());
            }
            if (signalingMechanismNode.has("delay")) {
              defaultAction.setDelay(signalingMechanismNode.path("delay").getIntValue());
            }
            if (signalingMechanismNode.has("sourceIdentifier")) {
              cue.setCueSource(signalingMechanismNode.path("sourceIdentifier").getTextValue());
            }

            trigger.getCues().add(cue);
            actionTriggers.add(trigger);
          }

        }
      }
    }

    com.pacoapp.paco.shared.model2.Feedback f = new com.pacoapp.paco.shared.model2.Feedback();
    if (rootNode.has("feedback")) {
      ArrayNode feedbackNodes = (ArrayNode) rootNode.path("feedback");
      JsonNode feedbackNode = feedbackNodes.get(0);
      if (feedbackNode.has("text")) {
        f.setText(feedbackNode.path("text").getTextValue());
      }

    }
    if (rootNode.has("feedbackType")) {
      f.setType(rootNode.path("feedbackType").getIntValue());
    }
    defaultExperimentGroup.setFeedback(f);
    ExperimentValidator validator = new ExperimentValidator();
    experimentDAO.validateWith(validator);
    List<ValidationMessage> results = validator.getResults();
    if (!results.isEmpty()) {
      if (results.size() == 1 && results.get(0).getMsg().equals("admins should be a valid list of email addresses")) {
        return; // OK to not have admins
      } else {
        Log.e(PacoConstants.TAG, "error migrating experiment: " + experimentDAO.getId() + ":\n" + Joiner.on(",").join(results));
      }
    }

  }

  static Experiment createExperiment(Cursor cursor) {
    int idIndex = cursor.getColumnIndex(ExperimentColumns._ID);
    int jsonIndex = cursor.getColumnIndex(ExperimentColumns.JSON);

    if (!cursor.isNull(jsonIndex)) {
      String jsonOfExperiment = cursor.getString(jsonIndex);
      try {
        long t1 = System.currentTimeMillis();
        Experiment experiment = ExperimentProviderUtil.getSingleExperimentFromJson(jsonOfExperiment);
        if (experiment.getId() == null) {
          if (!cursor.isNull(idIndex)) {
            experiment.setId(cursor.getLong(idIndex));
          }
        }
        Log.e(PacoConstants.TAG, "time to de-jsonify experiment (bytes: " + jsonOfExperiment.getBytes().length + ") : " + (System.currentTimeMillis() - t1));
        return experiment;
      } catch (JsonParseException e) {
        e.printStackTrace();
      } catch (JsonMappingException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }

    }
    return null;

  }

  static ContentValues createContentValues(Experiment experiment) {
    ContentValues values = new ContentValues();
    // Values id < 0 indicate no id is available:
    if (experiment.getId() != null) {
      values.put(ExperimentColumns._ID, experiment.getId());
    }
    if (experiment.getServerId() != null) {
      values.put(ExperimentColumns.SERVER_ID, experiment.getServerId());
    }
    if (experiment.getExperimentDAO().getTitle() != null) {
      values.put(ExperimentColumns.TITLE, experiment.getExperimentDAO().getTitle());
    }
    if (experiment.getJoinDate() != null) {
      values.put(ExperimentColumns.JOIN_DATE, experiment.getJoinDate());
    } else if (experiment.getExperimentDAO().getJoinDate() != null) {
      values.put(ExperimentColumns.JOIN_DATE, experiment.getExperimentDAO().getJoinDate());
    }

    long t1 = System.currentTimeMillis();
    String json = getJson(experiment);
    Log.e(PacoConstants.TAG, "time to jsonify experiment (bytes: " + json.getBytes().length + "): " + (System.currentTimeMillis() - t1));
    values.put(ExperimentColumns.JSON, json);
    return values;
  }

  // Visible for testing
  public List<String> getJsonList(List<Experiment> experiments) {
    List<String> experimentJsons = Lists.newArrayList();
    for (Experiment experiment : experiments) {
      experimentJsons.add(getJson(experiment));
    }
    return experimentJsons;
  }

  public static String getJson(Experiment experiment) {
    ObjectMapper mapper = JsonConverter.getObjectMapper();

    try {
      return mapper.writeValueAsString(experiment);
    } catch (JsonGenerationException e) {
      Log.e(PacoConstants.TAG, "Json generation error " + e);
    } catch (JsonMappingException e) {
      Log.e(PacoConstants.TAG, "JsonMapping error getting experiment json: " + e.getMessage());
    } catch (IOException e) {
      Log.e(PacoConstants.TAG, "IO error getting experiment: " + e.getMessage());
    }

    return null;

  }

  public static String getJson(List<Experiment> experiments) {
    ObjectMapper mapper = JsonConverter.getObjectMapper();

    try {
      return mapper.writeValueAsString(experiments);
    } catch (JsonGenerationException e) {
      Log.e(PacoConstants.TAG, "Json generation error " + e);
    } catch (JsonMappingException e) {
      Log.e(PacoConstants.TAG, "JsonMapping error getting experiment json: " + e.getMessage());
    } catch (IOException e) {
      Log.e(PacoConstants.TAG, "IO error getting experiment: " + e.getMessage());
    }

    return null;
  }

  public void loadEventsForExperiment(Experiment experiment) {
    List<Event> eventSingleEntryList = findEventsBy(EventColumns.EXPERIMENT_ID + "=" + experiment.getId(),
        EventColumns._ID +" DESC");
    experiment.setEvents(eventSingleEntryList);
  }

  public List<Event> loadEventsForExperimentByServerId(Long serverId) {
    return findEventsBy(EventColumns.EXPERIMENT_SERVER_ID + " = " + Long.toString(serverId),
        EventColumns._ID +" DESC");
  }

  public Uri insertEvent(Event event) {
    Uri uri = contentResolver.insert(EventColumns.CONTENT_URI, createContentValues(event));
    long rowId = Long.parseLong(uri.getLastPathSegment());
    event.setId(rowId);
    for (Output response : event.getResponses()) {
      response.setEventId(rowId);
      insertResponse(response);
    }
    return uri;
  }

  public void insertEvent(EventInterface eventI) {
    if (eventI instanceof Event) {
      Event event = (Event)eventI;
      insertEvent(event);
    }
  }

  private ContentValues createContentValues(Event event) {
    ContentValues values = new ContentValues();

    if (event.getId() >= 0) {
      values.put(EventColumns._ID, event.getId());
    }
    if (event.getExperimentId() >= 0) {
      values.put(EventColumns.EXPERIMENT_ID, event.getExperimentId());
    }
    if (event.getExperimentServerId() >= 0) {
      values.put(EventColumns.EXPERIMENT_SERVER_ID, event.getExperimentServerId());
    }
    if (event.getExperimentVersion() != null) {
      values.put(EventColumns.EXPERIMENT_VERSION, event.getExperimentVersion());
    }
    if (event.getExperimentName() != null) {
      values.put(EventColumns.EXPERIMENT_NAME, event.getExperimentName());
    }

    if (event.getScheduledTime() != null) {
      values.put(EventColumns.SCHEDULE_TIME, event.getScheduledTime().getMillis());
    }
    if (event.getResponseTime() != null) {
      values.put(EventColumns.RESPONSE_TIME, event.getResponseTime().getMillis());
    }

    if (event.getExperimentGroupName() != null) {
      values.put(EventColumns.GROUP_NAME, event.getExperimentGroupName());
    }
    if (event.getActionTriggerId() != null) {
      values.put(EventColumns.ACTION_TRIGGER_ID, event.getActionTriggerId());
    }
    if (event.getActionTriggerSpecId() != null) {
      values.put(EventColumns.ACTION_TRIGGER_SPEC_ID, event.getActionTriggerSpecId());
    }
    if (event.getActionId() != null) {
      values.put(EventColumns.ACTION_ID, event.getActionId());
    }

    values.put(EventColumns.UPLOADED, event.isUploaded() ? 1 : 0);

    return values;
  }

  private Uri insertResponse(Output response) {
    return contentResolver.insert(OutputColumns.CONTENT_URI,
        createContentValues(response));
  }

  private ContentValues createContentValues(Output response) {
    ContentValues values = new ContentValues();

    if (response.getId() >= 0) {
      values.put(OutputColumns._ID, response.getId());
    }
    if (response.getEventId() >= 0) {
      values.put(OutputColumns.EVENT_ID, response.getEventId());
    }
    if (response.getAnswer() != null) {
      values.put(OutputColumns.ANSWER, response.getAnswer());
    }
    if (response.getName() != null) {
      values.put(OutputColumns.NAME, response.getName());
    }
    return values;
  }

  private Event findEventBy(String select, String[] selectionArgs, String sortOrder) {
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(EventColumns.CONTENT_URI,
          null, select, selectionArgs, sortOrder);
      if (cursor != null && cursor.moveToNext()) {
        Event event = createEvent(cursor);
        event.setResponses(findResponsesFor(event));
        return event;
      }
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return null;
  }

  private List<Event> findEventsBy(String select, String sortOrder) {
    List<Event> events = new ArrayList<Event>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(EventColumns.CONTENT_URI,
          null, select, null, sortOrder);
      if (cursor != null) {
        while (cursor.moveToNext()) {
          Event event = createEvent(cursor);
          event.setResponses(findResponsesFor(event));
          events.add(event);
        }
      }
      return events;
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return events;
  }

  private List<Output> findResponsesFor(Event event) {
    List<Output> responses = new ArrayList<Output>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(OutputColumns.CONTENT_URI,
          null,
          OutputColumns.EVENT_ID + "=" + event.getId(),
          null,
          OutputColumns.INPUT_SERVER_ID + " ASC"); // TODO (bobevans) module the conditional questions, this ordering should be OK to get questions in order.
      if (cursor != null) {
        while (cursor.moveToNext()) {
          responses.add(createResponse(cursor));
        }
      }
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return responses;
  }

  private Event createEvent(Cursor cursor) {
    int idIndex = cursor.getColumnIndexOrThrow(EventColumns._ID);
    int experimentIdIndex = cursor.getColumnIndexOrThrow(EventColumns.EXPERIMENT_ID);
    int experimentServerIdIndex = cursor.getColumnIndex(EventColumns.EXPERIMENT_SERVER_ID);
    int experimentVersionIndex = cursor.getColumnIndex(EventColumns.EXPERIMENT_VERSION);
    int experimentNameIndex = cursor.getColumnIndex(EventColumns.EXPERIMENT_NAME);
    int scheduleTimeIndex = cursor.getColumnIndex(EventColumns.SCHEDULE_TIME);
    int responseTimeIndex = cursor.getColumnIndex(EventColumns.RESPONSE_TIME);
    int uploadedIndex = cursor.getColumnIndex(EventColumns.UPLOADED);
    int groupNameIndex = cursor.getColumnIndex(EventColumns.GROUP_NAME);
    int actionTriggerIndex = cursor.getColumnIndex(EventColumns.ACTION_TRIGGER_ID);
    int actionTriggerSpecIndex = cursor.getColumnIndex(EventColumns.ACTION_TRIGGER_SPEC_ID);
    int actionIdIndex = cursor.getColumnIndex(EventColumns.ACTION_ID);
    Event event = new Event();

    if (!cursor.isNull(idIndex)) {
      event.setId(cursor.getLong(idIndex));
    }

    if (!cursor.isNull(experimentIdIndex)) {
      event.setExperimentId(cursor.getLong(experimentIdIndex));
    }

    if (!cursor.isNull(experimentServerIdIndex)) {
      event.setServerExperimentId(cursor.getLong(experimentServerIdIndex));
    }
    if (!cursor.isNull(experimentVersionIndex)) {
      event.setExperimentVersion(cursor.getInt(experimentVersionIndex));
    }
    if (!cursor.isNull(experimentNameIndex)) {
      event.setExperimentName(cursor.getString(experimentNameIndex));
    }

    if (!cursor.isNull(responseTimeIndex)) {
      event.setResponseTime(new DateTime(cursor.getLong(responseTimeIndex)));
    }
    if (!cursor.isNull(scheduleTimeIndex)) {
      event.setScheduledTime(new DateTime(cursor.getLong(scheduleTimeIndex)));
    }
    if (!cursor.isNull(uploadedIndex)) {
      event.setUploaded(cursor.getInt(uploadedIndex) == 1);
    }

    if (!cursor.isNull(groupNameIndex)) {
      event.setExperimentGroupName(cursor.getString(groupNameIndex));
    }
    if (!cursor.isNull(actionTriggerIndex)) {
      event.setActionTriggerId(cursor.getLong(actionTriggerIndex));
    }
    if (!cursor.isNull(actionTriggerSpecIndex)) {
      event.setActionTriggerSpecId(cursor.getLong(actionTriggerSpecIndex));
    }
    if (!cursor.isNull(actionIdIndex)) {
      event.setActionId(cursor.getLong(actionIdIndex));
    }
    return event;
  }

  private Output createResponse(Cursor cursor) {
    int idIndex = cursor.getColumnIndexOrThrow(OutputColumns._ID);
    int eventIdIndex = cursor.getColumnIndexOrThrow(OutputColumns.EVENT_ID);
    int inputServeridIndex = cursor.getColumnIndex(OutputColumns.INPUT_SERVER_ID);
    int answerIndex = cursor.getColumnIndex(OutputColumns.ANSWER);
    int nameIndex = cursor.getColumnIndex(OutputColumns.NAME);

    Output input = new Output();

    if (!cursor.isNull(idIndex)) {
      input.setId(cursor.getLong(idIndex));
    }

    if (!cursor.isNull(eventIdIndex)) {
      input.setEventId(cursor.getLong(eventIdIndex));
    }

    if (!cursor.isNull(inputServeridIndex)) {
      input.setInputServerId(cursor.getLong(inputServeridIndex));
    }
    if (!cursor.isNull(nameIndex)) {
      input.setName(cursor.getString(nameIndex));
    }
    if (!cursor.isNull(answerIndex)) {
      input.setAnswer(cursor.getString(answerIndex));
    }
    return input;
  }

  public void updateEvent(EventInterface eventI) {
    if (eventI instanceof Event) {
      Event event = (Event)eventI;
      contentResolver.update(EventColumns.CONTENT_URI,
          createContentValues(event), "_id=" + event.getId(), null);
    } else {
      throw new IllegalArgumentException("I only know how to deal with Android objects!");
    }
  }

  public List<Event> getEventsNeedingUpload() {
    String select = EventColumns.UPLOADED + " != 1";
    return findEventsBy(select, null);
  }

  public List<Event> getAllEvents() {
    return findEventsBy(null, null);
  }

  public NotificationHolder getNotificationForSource(long experimentId, String source) {
    String[] selectionArgs = new String[] {Long.toString(experimentId), source};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ? and " + NotificationHolderColumns.NOTIFICATION_SOURCE + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      if (cursor.moveToFirst()) {
        return createNotification(cursor);
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return null;
  }

  public NotificationHolder getNotificationForAction(long experimentId, Long actionId) {
    String[] selectionArgs = new String[] {Long.toString(experimentId), Long.toString(actionId)};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ? and " + NotificationHolderColumns.ACTION_ID + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      if (cursor.moveToFirst()) {
        return createNotification(cursor);
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return null;
  }

  public List<NotificationHolder> getNotificationsFor(long experimentId, String experimentGroupName) {
    List<NotificationHolder> holders = new ArrayList<NotificationHolder>();
    String[] selectionArgs = new String[] {Long.toString(experimentId), experimentGroupName};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ? and " + NotificationHolderColumns.EXPERIMENT_GROUP_NAME + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      while (cursor.moveToNext()) {
        holders.add(createNotification(cursor));
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return holders;
  }

  private NotificationHolder createNotification(Cursor cursor) {
    int idIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns._ID);
    int experimentIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.EXPERIMENT_ID);
    int alarmIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.ALARM_TIME);
    int noticeCountIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.NOTICE_COUNT);
    int timeoutMillisIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.TIMEOUT_MILLIS);
    int notificationSourceIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.NOTIFICATION_SOURCE);
    int customMessageIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.CUSTOM_MESSAGE);
    int snoozeCountIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.SNOOZE_COUNT);
    int snoozeTimeIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.SNOOZE_TIME);
    int groupNameIndexIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.EXPERIMENT_GROUP_NAME);
    int actionTriggerIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.ACTION_TRIGGER_ID);
    int actionTriggerSpecIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.ACTION_TRIGGER_SPEC_ID);
    int actionIdIndex = cursor.getColumnIndexOrThrow(NotificationHolderColumns.ACTION_ID);

    NotificationHolder notification = new NotificationHolder();

    if (!cursor.isNull(idIndex)) {
      notification.setId(cursor.getLong(idIndex));
    }

    if (!cursor.isNull(experimentIdIndex)) {
      notification.setExperimentId(cursor.getLong(experimentIdIndex));
    }

    if (!cursor.isNull(alarmIdIndex)) {
      notification.setAlarmTime(cursor.getLong(alarmIdIndex));
    }
    if (!cursor.isNull(noticeCountIdIndex)) {
      notification.setNoticeCount(cursor.getInt(noticeCountIdIndex));
    }

    if (!cursor.isNull(timeoutMillisIdIndex)) {
      notification.setTimeoutMillis(cursor.getLong(timeoutMillisIdIndex));
    }

    if (!cursor.isNull(notificationSourceIndex)) {
      notification.setNotificationSource(cursor.getString(notificationSourceIndex));
    }
    if (!cursor.isNull(customMessageIndex)) {
      notification.setMessage(cursor.getString(customMessageIndex));
    }
    if (!cursor.isNull(snoozeCountIndex)) {
      notification.setSnoozeCount(cursor.getInt(snoozeCountIndex));
    }

    if (!cursor.isNull(snoozeTimeIndex)) {
      notification.setSnoozeTime(cursor.getInt(snoozeTimeIndex));
    }

    if (!cursor.isNull(groupNameIndexIndex)) {
      notification.setExperimentGroupName(cursor.getString(groupNameIndexIndex));
    }
    if (!cursor.isNull(actionTriggerIdIndex)) {
      notification.setActionTriggerId(cursor.getLong(actionTriggerIdIndex));
    }

    if (!cursor.isNull(actionTriggerSpecIdIndex)) {
      notification.setActionTriggerSpecId(cursor.getLong(actionTriggerSpecIdIndex));
    }

    if (!cursor.isNull(actionIdIndex)) {
      notification.setActionId(cursor.getLong(actionIdIndex));
    }

    return notification;
  }

  public Uri insertNotification(NotificationHolder notification) {
    Uri uri = contentResolver.insert(NotificationHolderColumns.CONTENT_URI,
        createContentValues(notification));
    long rowId = Long.parseLong(uri.getLastPathSegment());
    notification.setId(rowId);
    return uri;
  }

  public NotificationHolder getNotificationById(long notificationId) {
    String[] selectionArgs = new String[] {Long.toString(notificationId)};
    String selectionClause = NotificationHolderColumns._ID + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      if (cursor.moveToFirst()) {
        return createNotification(cursor);
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return null;
  }

  public void deleteNotification(long notificationId) {
    NotificationHolder holder = getNotificationById(notificationId);
    if (holder != null) {
      Log.i(PacoConstants.TAG, "found notificationHolder: " + holder.getId());
      deleteNotification(holder);
    }

  }

  private void deleteNotification(NotificationHolder holder) {
    if (holder != null) {
      String[] selectionArgs = new String[] {Long.toString(holder.getId())};
      String selectionClause = NotificationHolderColumns._ID + " = ?";
      int res = contentResolver.delete(NotificationHolderColumns.CONTENT_URI,
          selectionClause, selectionArgs);
      Log.i(PacoConstants.TAG, "resultof deleting notificationHolder: " + holder.getId() +" = " + res);
    }
  }

  public int deleteNotificationsForExperiment(Long experimentId) {
    if (experimentId == null) {
      return 0;
    }

    String[] selectionArgs = new String[] {Long.toString(experimentId)};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ?";
    return contentResolver.delete(NotificationHolderColumns.CONTENT_URI,
        selectionClause,
        selectionArgs);
  }

  public int updateNotification(NotificationHolder notification) {
    String[] selectionArgs = new String[] {Long.toString(notification.getId())};
    String selectionClause = NotificationHolderColumns._ID +" = ?";

    return contentResolver.update(NotificationHolderColumns.CONTENT_URI,
        createContentValues(notification),
        selectionClause, selectionArgs);
  }

  private ContentValues createContentValues(NotificationHolder notification) {
    ContentValues values = new ContentValues();

    if (notification.getId() != null) {
      values.put(NotificationHolderColumns._ID, notification.getId());
    }
    if (notification.getAlarmTime() != null) {
      values.put(NotificationHolderColumns.ALARM_TIME, notification.getAlarmTime() );
    }
    if (notification.getExperimentId() != null) {
      values.put(NotificationHolderColumns.EXPERIMENT_ID, notification.getExperimentId());
    }
    if (notification.getNoticeCount() != null) {
      values.put(NotificationHolderColumns.NOTICE_COUNT, notification.getNoticeCount());
    }
    if (notification.getTimeoutMillis() != null) {
      values.put(NotificationHolderColumns.TIMEOUT_MILLIS, notification.getTimeoutMillis());
    }
    if (notification.getNotificationSource() != null) {
      values.put(NotificationHolderColumns.NOTIFICATION_SOURCE, notification.getNotificationSource());
    }
    if (notification.getMessage() != null) {
      values.put(NotificationHolderColumns.CUSTOM_MESSAGE, notification.getMessage());
    }
    if (notification.getSnoozeCount() != null) {
      values.put(NotificationHolderColumns.SNOOZE_COUNT, notification.getSnoozeCount());
    }
    if (notification.getSnoozeTime() != null) {
      values.put(NotificationHolderColumns.SNOOZE_TIME, notification.getSnoozeTime());
    }
    if (notification.getExperimentGroupName() != null) {
      values.put(NotificationHolderColumns.EXPERIMENT_GROUP_NAME, notification.getExperimentGroupName());
    }
    if (notification.getActionTriggerId() != null) {
      values.put(NotificationHolderColumns.ACTION_TRIGGER_ID, notification.getActionTriggerId());
    }
    if (notification.getActionTriggerSpecId() != null) {
      values.put(NotificationHolderColumns.ACTION_TRIGGER_SPEC_ID, notification.getActionTriggerSpecId());
    }
    if (notification.getActionId() != null) {
      values.put(NotificationHolderColumns.ACTION_ID, notification.getActionId());
    }
    return values;
  }

  public List<NotificationHolder> getNotificationsStillActive(DateTime now) {
    List<NotificationHolder> notifs = new ArrayList<NotificationHolder>();

    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, null, null, null);
      while (cursor.moveToNext()) {

        NotificationHolder notif = createNotification(cursor);
        if (notif.isActive(now)) {
          notifs.add(notif);
        }
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return notifs;
  }

  public List<NotificationHolder> getAllNotifications() {
    List<NotificationHolder> notifs = new ArrayList<NotificationHolder>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, null, null, null);
      while (cursor.moveToNext()) {
        notifs.add(createNotification(cursor));
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return notifs;
  }

  public void saveMyExperimentsToDisk(String contentAsString) throws IOException {
    FileOutputStream fos = context.openFileOutput(MY_EXPERIMENTS_FILENAME, Context.MODE_PRIVATE);
    fos.write(contentAsString.getBytes());
    fos.close();
  }

  public List<Experiment> loadMyExperimentsFromDisk() {
    List<Experiment> experiments = null;
    try {
      experiments = createObjectsFromJsonStream(context.openFileInput(MY_EXPERIMENTS_FILENAME));
    } catch (IOException e) {
      Log.i(PacoConstants.TAG, "IOException, experiments file does not exist. May be first launch.");
    }
    return ensureExperiments(experiments);
  }

  public void saveExperimentsToDisk(String contentAsString) throws IOException {
    FileOutputStream fos = context.openFileOutput(PUBLIC_EXPERIMENTS_FILENAME, Context.MODE_PRIVATE);
    fos.write(contentAsString.getBytes());
    fos.close();
  }

  public List<Experiment> loadExperimentsFromDisk(boolean myExperimentsFile) {
    String filename = null;
    if (myExperimentsFile) {
      filename = MY_EXPERIMENTS_FILENAME;
    } else {
      filename = PUBLIC_EXPERIMENTS_FILENAME;
    }
    List<Experiment> experiments = null;
    try {
      FileInputStream openFileInput = context.openFileInput(filename);
      experiments = createObjectsFromJsonStream(openFileInput);
    } catch (IOException e) {
      Log.i(PacoConstants.TAG, "IOException, experiments file does not exist. May be first launch.");
    }
    return ensureExperiments(experiments);
  }

  public static void deleteExperimentCachesOnDisk(Context context2) {
    context2.deleteFile(MY_EXPERIMENTS_FILENAME);
    context2.deleteFile(PUBLIC_EXPERIMENTS_FILENAME);
  }

  public void addExperimentToExperimentsOnDisk(String contentAsString) {
    List<Experiment> existing = loadExperimentsFromDisk(false);
    List<Experiment> newEx;
    try {
      newEx = (List<Experiment>) fromDownloadedEntitiesJson(contentAsString).get("results");
      existing.addAll(newEx);
      String newJson = getJson(existing);
      if (newJson != null) {
        saveExperimentsToDisk(newJson);
      }
    } catch (JsonParseException e) {
    } catch (JsonMappingException e) {
    } catch (IOException e) {
    }

  }

  private List<Experiment> ensureExperiments(List<Experiment> experiments) {
    if (experiments != null) {
      return experiments;
    }
    return new ArrayList<Experiment>();
  }

  private List<Experiment> createObjectsFromJsonStream(FileInputStream fis) throws IOException, JsonParseException,
                                                                           JsonMappingException {
    try {
      ObjectMapper mapper = JsonConverter.getObjectMapper();
      return mapper.readValue(fis, new TypeReference<List<Experiment>>() {});
    } catch (Exception e) {
      e.printStackTrace();
    }
    return Lists.newArrayList();
  }

  private List<Experiment> createObjectsFromJsonStream(String fis) throws IOException, JsonParseException,
                                                                           JsonMappingException {
    try {
      ObjectMapper mapper = JsonConverter.getObjectMapper();
      return mapper.readValue(fis, new TypeReference<List<Experiment>>() {
      });
    } catch (Exception e) {
      e.printStackTrace();
    }
    return Lists.newArrayList();
  }

  public void loadLastEventForExperiment(Experiment experiment) {
    String select = EventColumns.EXPERIMENT_ID + "=" + experiment.getId();
    String sortOrder = EventColumns._ID +" DESC";

    List<Event> events = new ArrayList<Event>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(EventColumns.CONTENT_URI, null, select, null, sortOrder);
      if (cursor != null) {
        if (cursor.moveToFirst()) {
          Event event = createEvent(cursor);
          event.setResponses(findResponsesFor(event));
          events.add(event);
        }
      }
      experiment.setEvents(events);
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
  }

  public Experiment getExperimentFromDisk(Uri uri, boolean myExperimentsFile) {
    return getExperimentFromDisk(getExperimentServerIdFromUri(uri), myExperimentsFile);
  }

  public Long getExperimentServerIdFromUri(Uri uri) {
    return new Long(uri.getLastPathSegment());
  }

  public Experiment getExperimentFromDisk(Long experimentServerId, boolean myExperimentsFile) {
    List<Experiment> experiments= loadExperimentsFromDisk(myExperimentsFile);
    for (Experiment experiment : experiments) {
      if (experiment.getServerId().equals(experimentServerId)) {
        return experiment;
      }
    }
    return null;
  }

  public static Map<String, Object> fromEntitiesJson(String resultsJson) throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = JsonConverter.getObjectMapper();
    Map<String, Object> resultObjects = mapper.readValue(resultsJson, new TypeReference<Map<String, Object>>() {
    });
    Object experimentResults = resultObjects.get("results");
    String experimentJson = mapper.writeValueAsString(experimentResults);
    List<ExperimentDAO> experimentDAOs = mapper.readValue(experimentJson, new TypeReference<List<ExperimentDAO>>() {});

    List<Experiment> experiments = Lists.newArrayList();
    for (ExperimentDAO experimentDAO : experimentDAOs) {
      Experiment newExperiment = new Experiment();
      newExperiment.setExperimentDAO(experimentDAO);
      newExperiment.setServerId(experimentDAO.getId());
      experiments.add(newExperiment);
    }

    resultObjects.put("results", experiments);
    return resultObjects;
  }

  /**
   * this one wraps the downlaoded DAOs with Android Experiment objects
   * @param resultsJson
   * @return
   * @throws JsonParseException
   * @throws JsonMappingException
   * @throws IOException
   */
  public static Map<String, Object> fromDownloadedEntitiesJson(String resultsJson) throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = JsonConverter.getObjectMapper();

    Map<String, Object> resultObjects = mapper.readValue(resultsJson, new TypeReference<Map<String, Object>>() {});
    Object experimentResults = resultObjects.get("results");
    String experimentJson = mapper.writeValueAsString(experimentResults);
    List<ExperimentDAO> experiments = mapper.readValue(experimentJson, new TypeReference<List<ExperimentDAO>>() {
    });
    List<Experiment> experimentsWithDAOs = Lists.newArrayList();
    for (ExperimentDAO experimentDAO : experiments) {
      Experiment experiment = new Experiment();
      experiment.setExperimentDAO(experimentDAO);
      experimentsWithDAOs.add(experiment);
    }
    resultObjects.put("results", experimentsWithDAOs);
    return resultObjects;
  }

  public static List<Experiment> getExperimentsFromJson(String contentAsString) throws JsonParseException, JsonMappingException, IOException {
    Map<String, Object> results = fromDownloadedEntitiesJson(contentAsString);
    return (List<Experiment>) results.get("results");
  }

  public static Experiment getSingleExperimentFromJson(String contentAsString) throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = JsonConverter.getObjectMapper();
    return mapper.readValue(contentAsString, Experiment.class);
  }

  @Override
  public EventInterface getEvent(Long experimentServerId, DateTime scheduledTime,
                                 String groupName, Long actionTriggerId, Long scheduleId) {
    if (scheduledTime == null) {
      return null;
    }
    String selectionClause = EventColumns.EXPERIMENT_SERVER_ID + " = ? "
                              + " AND " + EventColumns.SCHEDULE_TIME + " = ? "
                              + " AND " + EventColumns.GROUP_NAME + " = ? "
                              + " AND " + EventColumns.ACTION_TRIGGER_ID + " = ? "
                              + " AND " + EventColumns.ACTION_TRIGGER_SPEC_ID + " = ? ";

    String[] selectionArgs = new String[] { Long.toString(experimentServerId),
                                          Long.toString(scheduledTime.getMillis()),
                                          groupName,
                                          Long.toString(actionTriggerId),
                                          Long.toString(scheduleId)};

    Event event = findEventBy(selectionClause, selectionArgs, EventColumns._ID +" DESC");
    if (event != null) {
      Log.i(PacoConstants.TAG, "Found event for experimentId: " + experimentServerId +", st = " + scheduledTime);
    } else {
      Log.i(PacoConstants.TAG, "DID NOT Find event for experimentId: " + experimentServerId +", st = " + scheduledTime);
    }
    return event;
  }

  public List<NotificationHolder> getAllNotificationsFor(Long experimentId) {
    List<NotificationHolder> holders = new ArrayList<NotificationHolder>();
    String[] selectionArgs = new String[] {Long.toString(experimentId)};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      while (cursor.moveToNext()) {
        holders.add(createNotification(cursor));
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return holders;
  }

  public List<NotificationHolder> getAllNotificationsFor(Long experimentId, String groupName) {
    List<NotificationHolder> holders = new ArrayList<NotificationHolder>();
    String[] selectionArgs = new String[] {Long.toString(experimentId), groupName};
    String selectionClause = NotificationHolderColumns.EXPERIMENT_ID + " = ? and "
            + NotificationHolderColumns.EXPERIMENT_GROUP_NAME + " = ?";
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(NotificationHolderColumns.CONTENT_URI,
        null, selectionClause, selectionArgs, null);
      while (cursor.moveToNext()) {
        holders.add(createNotification(cursor));
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return holders;
  }

  public void loadEventsForExperimentGroup(Experiment experiment, ExperimentGroup experimentGroup) {
    String[] args = new String[]{ Long.toString(experiment.getId()), experimentGroup.getName()};
    final String select = EventColumns.EXPERIMENT_ID + " = ? and " + EventColumns.GROUP_NAME + " = ?";
    List<Event> eventSingleEntryList = findEventsBy(select, args, EventColumns._ID + " DESC");
    experiment.setEvents(eventSingleEntryList);
  }

  private List<Event> findEventsBy(String select, String[] args, String sortOrder) {
    List<Event> events = new ArrayList<Event>();
    Cursor cursor = null;
    try {
      cursor = contentResolver.query(EventColumns.CONTENT_URI,
          null, select, args, sortOrder);
      if (cursor != null) {
        while (cursor.moveToNext()) {
          Event event = createEvent(cursor);
          event.setResponses(findResponsesFor(event));
          events.add(event);
        }
      }
      return events;
    } catch (RuntimeException e) {
      Log.w(ExperimentProvider.TAG, "Caught unexpected exception.", e);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return events;
  }

}


text:
package controllers

import com.mohiva.play.silhouette.api.exceptions.ProviderException
import com.mohiva.play.silhouette.api.util.{Clock, Credentials, PasswordHasher}
import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.impl.authenticators.{CookieAuthenticator, JWTAuthenticator}
import com.mohiva.play.silhouette.impl.exceptions.IdentityNotFoundException
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import com.omis.{User, UserReg}
import org.joda.time.DateTime
import play.api.Configuration
import play.api.i18n.{I18nSupport, Messages, MessagesApi}
import play.api.libs.json.Json
import play.api.mvc.Action
import _root_.services.{PasswordInfoService, UserService}
import utils.auth.DefaultEnv
import net.ceedubs.ficus.Ficus._

import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContext, Future}

class AuthController(userService: UserService, passwordInfoService: PasswordInfoService,
    val messagesApi: MessagesApi,
    passwordHasher: PasswordHasher,
    silhouette: Silhouette[DefaultEnv],
    credentialsProvider: CredentialsProvider,
    configuration: Configuration, clock: Clock)(implicit val ec: ExecutionContext) extends BaseController(silhouette) with I18nSupport {
  def login = Action.async(parse.json) { implicit request =>
    request.body.validate[UserReg].map { data =>
      credentialsProvider.authenticate(Credentials(data.regCode, data.password)).flatMap { loginInfo =>
        userService.retrieve(loginInfo).flatMap {
          case Some(user) => silhouette.env.authenticatorService.create(loginInfo).map {
            case authenticator => createAuthenticator(authenticator)
          }.flatMap { authenticator =>
            silhouette.env.eventBus.publish(LoginEvent(user, request))
            silhouette.env.authenticatorService.init(authenticator).map { token =>
              Ok(token)
            }
          }
          case None => Future.failed(new IdentityNotFoundException("Couldn't find user"))
        }
      }.recover {
        case e: ProviderException =>
          Unauthorized(Json.obj("message" -> Messages("invalid.credentials")))
      }
    }.recoverTotal {
      case error =>
        Future.successful(Unauthorized(Json.obj("message" -> Messages("invalid.credentials"))))
    }
  }

  private def createAuthenticator(authenticator: JWTAuthenticator) = {
    authenticator.copy(
      expirationDateTime = rememberMeParams._1,
      idleTimeout = rememberMeParams._2
    )
  }

  private lazy val rememberMeParams: (DateTime, Option[FiniteDuration], Option[FiniteDuration]) = {
    val cfg = configuration.getConfig("silhouette.authenticator.rememberMe").get.underlying
    (
      clock.now.plusSeconds(cfg.as[FiniteDuration]("authenticatorExpiry").toSeconds.toInt),
      cfg.getAs[FiniteDuration]("authenticatorIdleTimeout"),
      cfg.getAs[FiniteDuration]("cookieMaxAge")
    )
  }

  def authenticate = withSession("authenticate") {
    req =>
      Future(Ok(Json.toJson(User(req.identity.id, req.identity.role, req.identity.created.toString))))
  }

  def logout = silhouette.SecuredAction.async { implicit request =>
    silhouette.env.eventBus.publish(LogoutEvent(request.identity, request))
    silhouette.env.authenticatorService.discard(request.authenticator, Ok)
  }
}

redpajama_set_name: RedPajamaGithub


text:
Podcast To Playlist
===================

This is a Perl programme which parses podcast rss feeds and prints out a list of the media files published in that feed, in order of publication date.
Output is in m3u format by default, but you can set command line options to get CSV, JSON, pipe-delimited etc.

Dependencies
------------

You will need the following modules from CPAN (pr elsewhere) to use podcast2playlist:

 * LWP::UserAgent
 * XML::RSS::Parser
 * Date::Parse

Usage
-----

### Output an m3u from a podcast

	podcast2playlist.pl user "you@email.example" url http://test.test/podcast.xml > playlist.m3u

### Output an m3u from a local podcast file
	podcast2playlist.pl url localfile.xml > playlist.m3u

### Output a CSV from a podcast
	podcast2playlist.pl user "you@email.example" url http://test.test/podcast.xml delim "," > playlist.csv

### Output a single (most recent) item from a podcast
	podcast2playlist.pl user "you@email.example" url http://test.test/podcast.xml limit 1 > single-item-playlist.m3u

### Output the 5 most recent items from a podcast as a playlist in JSON
	podcast2playlist.pl user "you@email.example" url http://test.test/podcast.xml limit 5 delim '","url":"' output_start '[{"url":"' output_end '"}]'  > playlist.json

Note
----

Playlists are sorted by date, newest item first. Other sorting methods will appear some time when I can be bothered.


text:
/**
 * @file        src/common/request/MonitorGetEntriesRequest.cpp
 * @author      Zofia Abramowska <z.abramowska@samsung.com>
 * @version     1.0
 * @brief       This file implements monitor get entries request class
 */

#include <request/RequestTaker.h>

#include "MonitorGetEntriesRequest.h"

namespace Cynara {

void MonitorGetEntriesRequest::execute(RequestTaker &taker, const RequestContext &context) const {
    taker.execute(context, *this);
}

} // namespace Cynara


text:
package org.neuroph.util.io;

import org.neuroph.core.NeuralNetwork;

/**
 * <pre>
 * This class is helper for feeding neural network with data using some InputAdapter
 * and writing network output using OutputAdapter
 * </pre>
 * @see InputAdapter
 * @see OutputAdapter
 * @author Zoran Sevarac <sevarac@gmail.com>
 */
public class IOHelper {

    /**
     * Feeds specified neural network with data from InputAdapter and writes
     * output using OutputAdapter
     * @param neuralNet neural network
     * @param in input data source
     * @param out output data target
     */
    public static void process(NeuralNetwork neuralNet, InputAdapter in, OutputAdapter out) {

        double[] input;
        while( (input = in.readInput()) != null) {
            neuralNet.setInput(input);
            neuralNet.calculate();
            double[] output = neuralNet.getOutput();
            out.writeOutput(output);
        }

        in.close();
        out.close();
    }

}


text:
cask 'scapple' do
  version '1.3.4'
  sha256 '0f81d00286f0c49fafc03966bfb2c4dd9fc036495d69def64988d489223e7892'

  # scrivener.s3.amazonaws.com was verified as official when first introduced to the cask
  url 'https://scrivener.s3.amazonaws.com/Scapple.dmg'
  appcast 'https://www.literatureandlatte.com/downloads/scapple/scapple.xml'
  name 'Scapple'
  homepage 'https://www.literatureandlatte.com/scapple.php'

  app 'Scapple.app'
end


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;

namespace org.ohdsi.cdm.framework.core.CommonVocabulary
{
   [ServiceBehavior(MaxItemsInObjectGraph = int.MaxValue)]
   public class VocabularyService : IVocabularyService
   {
      public static Dictionary<string, long> providers = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);

      public void AddProviders(KeyValuePair<string, long>[] values)
      {
         foreach (var value in values)
         {
            if (providers.ContainsKey(value.Key)) continue;

            providers.Add(value.Key, value.Value);
         }
      }

      public KeyValuePair<string, long>[] GetProviderIds(string[] sources)
      {
         return
            sources.Select(
               source =>
               providers.ContainsKey(source)
                  ? new KeyValuePair<string, long>(source, providers[source])
                  : new KeyValuePair<string, long>(source, -1)).ToArray();
      }
   }
}


text:
package org.springframework.web.util;

import java.io.UnsupportedEncodingException;

import junit.framework.TestCase;
import android.test.suitebuilder.annotation.SmallTest;

/**
 * @author Arjen Poutsma
 * @author Roy Clarkson
 */
public class UriUtilsTests extends TestCase {

	private static final String ENC = "UTF-8";

	@SmallTest
	public void testEncodeScheme() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar+-.", UriUtils.encodeScheme("foobar+-.", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeScheme("foo bar", ENC));
	}

	@SmallTest
	public void testEncodeUserInfo() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar:", UriUtils.encodeUserInfo("foobar:", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeUserInfo("foo bar", ENC));
	}

	@SmallTest
	public void testEncodeHost() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar", UriUtils.encodeHost("foobar", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeHost("foo bar", ENC));
	}

	@SmallTest
	public void testEncodePort() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "80", UriUtils.encodePort("80", ENC));
	}

	@SmallTest
	public void testEncodePath() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "/foo/bar", UriUtils.encodePath("/foo/bar", ENC));
		assertEquals("Invalid encoded result", "/foo%20bar", UriUtils.encodePath("/foo bar", ENC));
		assertEquals("Invalid encoded result", "/Z%C3%BCrich", UriUtils.encodePath("/Z\u00fcrich", ENC));
	}

	@SmallTest
	public void testEncodePathSegment() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar", UriUtils.encodePathSegment("foobar", ENC));
		assertEquals("Invalid encoded result", "%2Ffoo%2Fbar", UriUtils.encodePathSegment("/foo/bar", ENC));
	}

	@SmallTest
	public void testEncodeQuery() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQuery("foobar", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQuery("foo bar", ENC));
		assertEquals("Invalid encoded result", "foobar/+", UriUtils.encodeQuery("foobar/+", ENC));
		assertEquals("Invalid encoded result", "T%C5%8Dky%C5%8D", UriUtils.encodeQuery("T\u014dky\u014d", ENC));
	}

	@SmallTest
	public void testEncodeQueryParam() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQueryParam("foobar", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQueryParam("foo bar", ENC));
		assertEquals("Invalid encoded result", "foo%26bar", UriUtils.encodeQueryParam("foo&bar", ENC));
	}

	@SmallTest
	public void testEncodeFragment() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded result", "foobar", UriUtils.encodeFragment("foobar", ENC));
		assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeFragment("foo bar", ENC));
		assertEquals("Invalid encoded result", "foobar/", UriUtils.encodeFragment("foobar/", ENC));
	}

	@SmallTest
	public void testDecode() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded URI", "", UriUtils.decode("", ENC));
		assertEquals("Invalid encoded URI", "foobar", UriUtils.decode("foobar", ENC));
		assertEquals("Invalid encoded URI", "foo bar", UriUtils.decode("foo%20bar", ENC));
		assertEquals("Invalid encoded URI", "foo+bar", UriUtils.decode("foo%2bbar", ENC));
		assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T%C5%8Dky%C5%8D", ENC));
		assertEquals("Invalid encoded result", "/Z\u00fcrich", UriUtils.decode("/Z%C3%BCrich", ENC));
		assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T\u014dky\u014d", ENC));
	}

	@SmallTest
	public void testDecodeInvalidSequence() throws UnsupportedEncodingException {
		boolean success = false;
		try {
			UriUtils.decode("foo%2", ENC);
		} catch (IllegalArgumentException e) {
			success = true;
		}
		assertTrue("expected IllegalArgumentException", success);
	}

	@SuppressWarnings("deprecation")
	@SmallTest
	public void testEncodeUri() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded URI", "http://www.ietf.org/rfc/rfc3986.txt",
				UriUtils.encodeUri("http://www.ietf.org/rfc/rfc3986.txt", ENC));
		assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt",
				UriUtils.encodeUri("https://www.ietf.org/rfc/rfc3986.txt", ENC));
		assertEquals("Invalid encoded URI", "http://www.google.com/?q=Z%C3%BCrich",
				UriUtils.encodeUri("http://www.google.com/?q=Z\u00fcrich", ENC));
		assertEquals("Invalid encoded URI",
				"http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)",
				UriUtils.encodeUri(
						"http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)",
						ENC));
		assertEquals("Invalid encoded URI", "http://java.sun.com/j2se/1.3/",
				UriUtils.encodeUri("http://java.sun.com/j2se/1.3/", ENC));
		assertEquals("Invalid encoded URI", "docs/guide/collections/designfaq.html#28",
				UriUtils.encodeUri("docs/guide/collections/designfaq.html#28", ENC));
		assertEquals("Invalid encoded URI", "../../../demo/jfc/SwingSet2/src/SwingSet2.java",
				UriUtils.encodeUri("../../../demo/jfc/SwingSet2/src/SwingSet2.java", ENC));
		assertEquals("Invalid encoded URI", "file:///~/calendar", UriUtils.encodeUri("file:///~/calendar", ENC));
		assertEquals("Invalid encoded URI", "http://example.com/query=foo@bar",
				UriUtils.encodeUri("http://example.com/query=foo@bar", ENC));

	}

	@SuppressWarnings("deprecation")
	@SmallTest
	public void testEncodeHttpUrl() throws UnsupportedEncodingException {
		assertEquals("Invalid encoded HTTP URL", "http://www.ietf.org/rfc/rfc3986.txt",
				UriUtils.encodeHttpUrl("http://www.ietf.org/rfc/rfc3986.txt", ENC));
		assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt",
				UriUtils.encodeHttpUrl("https://www.ietf.org/rfc/rfc3986.txt", ENC));
		assertEquals("Invalid encoded HTTP URL", "http://www.google.com/?q=Z%C3%BCrich",
				UriUtils.encodeHttpUrl("http://www.google.com/?q=Z\u00fcrich", ENC));
		assertEquals("Invalid encoded HTTP URL", "http://ws.geonames.org/searchJSON?q=T%C5%8Dky%C5%8D&style=FULL&maxRows=300",
				UriUtils.encodeHttpUrl("http://ws.geonames.org/searchJSON?q=T\u014dky\u014d&style=FULL&maxRows=300", ENC));
		assertEquals("Invalid encoded HTTP URL",
				"http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar",
				UriUtils.encodeHttpUrl(
						"http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar", ENC));
		assertEquals("Invalid encoded HTTP URL", "http://search.twitter.com/search.atom?q=%23avatar",
				UriUtils.encodeHttpUrl("http://search.twitter.com/search.atom?q=#avatar", ENC));
		assertEquals("Invalid encoded HTTP URL", "http://java.sun.com/j2se/1.3/",
				UriUtils.encodeHttpUrl("http://java.sun.com/j2se/1.3/", ENC));
		assertEquals("Invalid encoded HTTP URL", "http://example.com/query=foo@bar",
				UriUtils.encodeHttpUrl("http://example.com/query=foo@bar", ENC));

		// SPR-8974
		assertEquals("http://example.org?format=json&url=http://another.com?foo=bar",
				UriUtils.encodeUri("http://example.org?format=json&url=http://another.com?foo=bar", ENC));

		// ANDROID-76
		assertEquals("Invalid encoded HTTP URL",
				"http://query.yahooapis.com/v1/public/yql?q=select%20Date,%20Close,%20Volume%20from%20yahoo.finance.historicaldata%20where%20symbol%20=%20%22AAPL%22%20and%20startDate%20=%20%222012-01-01%22%20and%20endDate%20=%20%222012-01-10%22&format=json&env=store://datatables.org/alltableswithkeys",
				UriUtils.encodeHttpUrl("http://query.yahooapis.com/v1/public/yql?q=select Date, Close, Volume from yahoo.finance.historicaldata where symbol = \"AAPL\" and startDate = \"2012-01-01\" and endDate = \"2012-01-10\"&format=json&env=store://datatables.org/alltableswithkeys", ENC));
	}

	@SuppressWarnings("deprecation")
	@SmallTest
	public void testEncodeHttpUrlMail() throws UnsupportedEncodingException {
		boolean success = false;
		try {
			UriUtils.encodeHttpUrl("mailto:java-net@java.sun.com", ENC);
		} catch (IllegalArgumentException e) {
			success = true;
		}
		assertTrue("expected IllegalArgumentException", success);
	}

}


text:
<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace Mantenimiento\Services;
use Mantenimiento\Entities\Reparacion;
use Parametrizacion\Entities\EstadoActivo;
use Activos\Entities\Activo;
use Seguridad\Entities\Usuario;
/**
 *
 * @author MIGUEL
 */
interface IReparacionAdminService {

    public function initReparacion(Activo $activo ,Usuario $tecnico,$desripcion = "");

    public function updateReparacion(Reparacion $reparacion);

    public function getListReparaciones($filter = null);

    public function getReparacionbyId($id);

    public function getListReparacionesByIdActivo($id_activo,$filter = null);

    public function getListReparacionByIdTecnico($id_tecnico,$filter = null);

    public function terminateReparacion($id_reparacion,EstadoActivo $estado_final,$descripcion);

    public function getReparacionesPending($filter = null);

    public function getReparacionesTerminate($filter = null);

    public function getReparacionesPendingByIdActivo($id_activo,$filter = null);

    public function getReparacionesPendingByIdTecnico($id_tecnico,$filter = null);

    public function getReparacionesTerminateByIdActivo($id_activo,$filter = null);

    public function getReparacionesTerminateByIdTecnico($id_tecnico,$filter = null);

}


text:
module csComp.Services
{
    declare var Cesium;

    export class CesiumRenderer implements IMapRenderer
    {
        title = "cesium";
        service : LayerService;
        viewer : any;
        camera : any;
        features: { [key: string]: any } = {};

        public init(service : LayerService){
            this.service = service;
        }

        public enable()
        {
            this.viewer = new Cesium.Viewer('map');
            this.camera = this.viewer.camera;

            this.camera.setView({
                position : Cesium.Cartesian3.fromDegrees(5, 52, 1000000)
            });

            //console.log('project:');
            //console.log(this.service.project.features);
            for (var i = 0; i < this.service.project.features.length; ++i)
                this.addFeature(this.service.project.features[i]);
            $(".cesium-viewer-toolbar").hide();
        }

        public disable()
        {
            this.viewer.destroy();
            //$("#map").empty();
        }

        public addLayer(layer: ProjectLayer)
        {
            //alert('addLayer called');

            if (layer.type == "GeoJson")
            {
                var object:any = <Object> layer.data;

                if (object.type == null)
                    object.type = "FeatureCollection";

                var geoJSONPromise = Cesium.GeoJsonDataSource.load(object);

                Cesium.when(geoJSONPromise, (dataSource)=>
                {
                    layer.cesiumDatasource = dataSource;
                });

                this.viewer.dataSources.add(geoJSONPromise);
            }
            if (layer.type == "dynamicgeojson")
            {
                var object : any = (<any>layer.data).features;

                //fix for some datasources with incomplete json
                if (object.type == null)
                    object.type = "FeatureCollection";

                //console.log('adding layer');
                //console.log(object);

                object.forEach((f: IFeature) => {
                    this.addFeature(f);
                });
            }
            if (layer.type == "wms")
            {
                //todo
            }
        }

        public removeLayer(layer: ProjectLayer)
        {
            alert('removelayer called');
            if (layer.type == "GeoJson")
            {
                this.viewer.dataSources.remove(layer.cesiumDatasource);
            }
            if (layer.type == "wms")
            {
                //todo
            }
        }

        public updateMapFilter(group : ProjectGroup) {}

        public addGroup(group: ProjectGroup) { }

        public removeGroup(group: ProjectGroup) { }

        public createFeature(feature: IFeature) { }

        public removeFeature(feature: IFeature)
        {
            if (this.features.hasOwnProperty(feature.id)) {
                this.viewer.dataSources.remove(this.features[feature.id]);
                delete this.features[feature.id];
            }
        }

        public updateFeature( feature : IFeature)
        {
            this.removeFeature(feature);
            this.addFeature(feature);
        }

        public addFeature(feature: IFeature)
        {
            //alert('addFeature called');
            //console.log('added feature:');
            //console.log(feature);
            //var entity = new Cesium.Entity({ id: feature.index, name: feature.featureTypeName, position: new Cesium.Cartesian3.fromDegrees(feature.geometry.coordinates[0], feature.geometry.coordinates[1], feature.properties.Altitude) });
            //console.log('adding feature');
            //console.log(feature);

            //feature.coordinates = feature.coordinates
            //var entity = this.createEntity(feature);

            var dataSourcePromise = Cesium.GeoJsonDataSource.load(feature);

            Cesium.when(dataSourcePromise, (dataSource) => {

                //dataSource.entities.entities[0].billboard = null;
                //dataSource.entities.entities[0].model = new Cesium.ModelGraphics({ uri: '/models/plane.gltf', minimumPixelSize: 100 });

                this.features[feature.id] = dataSource;
                this.viewer.dataSources.add(dataSource);
            });

        }

    }
}


text:
namespace MassTransit.EventHubIntegration
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Azure;
    using Azure.Messaging.EventHubs;
    using Azure.Messaging.EventHubs.Processor;
    using Azure.Storage.Blobs;
    using MassTransit.Configuration;
    using MassTransit.Middleware;

    public class EventHubProcessorContext :
        BasePipeContext,
        ProcessorContext
    {
        readonly BlobContainerClient _blobContainerClient;
        readonly EventProcessorClient _client;
        readonly IProcessorLockContext _lockContext;

        public EventHubProcessorContext(IHostConfiguration hostConfiguration, ReceiveSettings receiveSettings, BlobContainerClient blobContainerClient,
            EventProcessorClient client, Func<PartitionInitializingEventArgs, Task> partitionInitializingHandler,
            Func<PartitionClosingEventArgs, Task> partitionClosingHandler, CancellationToken cancellationToken)
            : base(cancellationToken)
        {
            _blobContainerClient = blobContainerClient;
            _client = client;

            var lockContext = new ProcessorLockContext(hostConfiguration, receiveSettings);
            _client.PartitionInitializingAsync += async args =>
            {
                await lockContext.OnPartitionInitializing(args).ConfigureAwait(false);
                if (partitionInitializingHandler != null)
                    await partitionInitializingHandler(args).ConfigureAwait(false);
            };
            _client.PartitionClosingAsync += async args =>
            {
                if (partitionClosingHandler != null)
                    await partitionClosingHandler(args).ConfigureAwait(false);
                await lockContext.OnPartitionClosing(args).ConfigureAwait(false);
            };
            _client.ProcessErrorAsync += OnError;
            _client.ProcessEventAsync += OnMessage;

            ReceiveSettings = receiveSettings;
            _lockContext = lockContext;
        }

        public event Func<ProcessEventArgs, Task> ProcessEvent;
        public event Func<ProcessErrorEventArgs, Task> ProcessError;

        public ReceiveSettings ReceiveSettings { get; }

        public async Task<bool> CreateBlobIfNotExistsAsync(CancellationToken cancellationToken = default)
        {
            Response<bool> exists = await _blobContainerClient.ExistsAsync(cancellationToken).ConfigureAwait(false);
            if (exists.Value)
                return true;

            try
            {
                await _blobContainerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
                return true;
            }
            catch (RequestFailedException exception)
            {
                LogContext.Warning?.Log(exception, "Azure Blob Container does not exist: {Address}", _blobContainerClient.Uri);
                return false;
            }
        }

        public Task StartProcessingAsync(CancellationToken cancellationToken = default)
        {
            return _client.StartProcessingAsync(cancellationToken);
        }

        public Task StopProcessingAsync(CancellationToken cancellationToken = default)
        {
            return _client.StopProcessingAsync(cancellationToken);
        }

        public Task Pending(ProcessEventArgs eventArgs)
        {
            return _lockContext.Pending(eventArgs);
        }

        public Task Faulted(ProcessEventArgs eventArgs, Exception exception)
        {
            return _lockContext.Faulted(eventArgs, exception);
        }

        public Task Complete(ProcessEventArgs eventArgs)
        {
            return _lockContext.Complete(eventArgs);
        }

        async Task OnError(ProcessErrorEventArgs arg)
        {
            if (ProcessError != null)
                await ProcessError.Invoke(arg).ConfigureAwait(false);
        }

        async Task OnMessage(ProcessEventArgs arg)
        {
            if (!arg.HasEvent)
                return;

            await _lockContext.Pending(arg).ConfigureAwait(false);

            if (ProcessEvent != null)
                await ProcessEvent.Invoke(arg).ConfigureAwait(false);
        }
    }
}