text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Composition;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;

namespace Microsoft.CodeAnalysis.Remote.Diagnostics
{
    /// <summary>
    /// Customizes the path where to store shadow-copies of analyzer assemblies.
    /// </summary>
    [ExportWorkspaceService(typeof(IAnalyzerAssemblyLoaderProvider), WorkspaceKind.RemoteWorkspace), Shared]
    internal sealed class RemoteAnalyzerAssemblyLoaderService : IAnalyzerAssemblyLoaderProvider
    {
        private readonly RemoteAnalyzerAssemblyLoader _loader;
        private readonly ShadowCopyAnalyzerAssemblyLoader _shadowCopyLoader;

        [ImportingConstructor]
        [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
        public RemoteAnalyzerAssemblyLoaderService()
        {
            var baseDirectory = Path.GetDirectoryName(Path.GetFullPath(typeof(RemoteAnalyzerAssemblyLoader).GetTypeInfo().Assembly.Location));
            Debug.Assert(baseDirectory != null);

            _loader = new(baseDirectory);
            _shadowCopyLoader = new(Path.Combine(Path.GetTempPath(), "VS", "AnalyzerAssemblyLoader"));
        }

        public IAnalyzerAssemblyLoader GetLoader(in AnalyzerAssemblyLoaderOptions options)
            => options.ShadowCopy ? _shadowCopyLoader : _loader;

        // For analyzers shipped in Roslyn, different set of assemblies might be used when running
        // in-proc and OOP e.g. in-proc (VS) running on desktop clr and OOP running on ServiceHub .Net6
        // host. We need to make sure to use the ones from the same location as the remote.
        private class RemoteAnalyzerAssemblyLoader : DefaultAnalyzerAssemblyLoader
        {
            private readonly string _baseDirectory;

            protected override Assembly LoadImpl(string fullPath)
                => base.LoadImpl(FixPath(fullPath));

            public RemoteAnalyzerAssemblyLoader(string baseDirectory)
            {
                _baseDirectory = baseDirectory;
            }

            private string FixPath(string fullPath)
            {
                var fixedPath = Path.GetFullPath(Path.Combine(_baseDirectory, Path.GetFileName(fullPath)));
                return File.Exists(fixedPath) ? fixedPath : fullPath;
            }
        }
    }
}


text:
package org.efaps.admin.user;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.efaps.ci.CIAdminUser;
import org.efaps.db.Context;
import org.efaps.db.Instance;
import org.efaps.db.wrapper.SQLPart;
import org.efaps.db.wrapper.SQLSelect;
import org.efaps.util.EFapsException;
import org.efaps.util.cache.CacheLogListener;
import org.efaps.util.cache.CacheReloadException;
import org.efaps.util.cache.InfinispanCache;
import org.infinispan.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class represents the instance of a group in eFaps.
 *
 * @author The eFaps Team
 *
 */
public final class Group
    extends AbstractUserObject
{
    /**
     * Needed for serialization.
     */
    private static final long serialVersionUID = 1L;

    /**
     * Logging instance used in this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(Group.class);

    /**
     * This is the SQL select statement to select a Group from the database by ID.
     */
    private static final String SQL_ID = new SQLSelect().column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("STATUS")
                    .from("V_USERGROUP", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();

    /**
     * This is the SQL select statement to select a Group from the database by Name.
     */
    private static final String SQL_NAME = new SQLSelect().column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("STATUS")
                    .from("V_USERGROUP", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "NAME").addPart(SQLPart.EQUAL).addValuePart("?")
                    .toString();

    /**
     * This is the SQL select statement to select a Group from the database by UUID.
     */
    private static final String SQL_UUID = new SQLSelect().column("ID")
                    .column("UUID")
                    .column("NAME")
                    .column("STATUS")
                    .from("V_USERGROUP", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
                    .toString();

    /**
     * This is the SQL select statement to select a Group from the database using the JAAS key..
     */
    private static final String SQL_JAASKEY = new SQLSelect().column("ID")
                    .from("V_USERGROUPJASSKEY", 0)
                    .addPart(SQLPart.WHERE).addColumnPart(0, "JAASKEY").addPart(SQLPart.EQUAL).addValuePart("?")
                    .addPart(SQLPart.AND).addColumnPart(0, "JAASSYSID").addPart(SQLPart.EQUAL).addValuePart("?")
                    .toString();

    /**
     * Name of the Cache by ID.
     */
    private static final String IDCACHE = Group.class.getName() + ".ID";

    /**
     * Name of the Cache by Name.
     */
    private static final String NAMECACHE = Group.class.getName() + ".Name";

    /**
     * Name of the Cache by Name.
     */
    private static final String UUIDCACHE = Group.class.getName() + ".UUID";

    /**
     * Use to mark not found and return null.
     */
    private static final Group NULL = new Group(0, null, null, false);

    /**
     * Create a new group instance. The method is used from the static method
     * {@link #initialize()} to read all groups from the database.
     *
     * @param _id       id of the group
     * @param _uuid     UUID of the group
     * @param _name     name of the group
     * @param _status   status of the group
     */
    private Group(final long _id,
                  final String _uuid,
                  final String _name,
                  final boolean _status)
    {
        super(_id, _uuid, _name, _status);
    }

    /**
     * Returns the viewable name of the group. The method {@link #getName} is
     * used for the viewing name.
     *
     * @param _context  context for this request
     * @return name of the group
     * @see #getName
     */
    public String getViewableName(final Context _context)
    {
        return getName();
    }

    /**
     * Checks, if the given person is assigned to this group.
     *
     * @param _person   person to test
     * @return true if the person is assigned to this group, otherwise
     *         false
     * @see Person#isAssigned(Group)
     */
    @Override
    public boolean hasChildPerson(final Person _person)
    {
        return _person.isAssigned(this);
    }

    @Override
    public Instance getInstance()
    {
        return Instance.get(CIAdminUser.Group.getType(), getId());
    }

    @Override
    public boolean equals(final Object _obj)
    {
        final boolean ret;
        if (_obj instanceof Group) {
            ret = ((Group) _obj).getId() == getId();
        } else {
            ret = super.equals(_obj);
        }
        return ret;
    }

    @Override
    public int hashCode()
    {
        return  Long.valueOf(getId()).intValue();
    }

    /**
     * Method to initialize the Cache of this CacheObjectInterface.
     *
     * @see #CACHE
     */
    public static void initialize()
    {
        if (InfinispanCache.get().exists(Group.IDCACHE)) {
            InfinispanCache.get().<Long, Group>getCache(Group.IDCACHE).clear();
        } else {
            InfinispanCache.get().<Long, Group>getCache(Group.IDCACHE).addListener(new CacheLogListener(Group.LOG));
        }
        if (InfinispanCache.get().exists(Group.NAMECACHE)) {
            InfinispanCache.get().<String, Group>getCache(Group.NAMECACHE).clear();
        } else {
            InfinispanCache.get().<String, Group>getCache(Group.NAMECACHE).addListener(new CacheLogListener(Group.LOG));
        }
        if (InfinispanCache.get().exists(Group.UUIDCACHE)) {
            InfinispanCache.get().<UUID, Group>getCache(Group.UUIDCACHE).clear();
        } else {
            InfinispanCache.get().<UUID, Group>getCache(Group.UUIDCACHE).addListener(new CacheLogListener(Group.LOG));
        }
    }

    /**
     * Returns for given parameter _id the instance of class
     * {@link Group}.
     *
     * @param _id id to search in the cache
     * @return instance of class {@link Group}
     * @throws CacheReloadException on error
     */
    public static Group get(final long _id)
        throws CacheReloadException
    {
        final Cache<Long, Group> cache = InfinispanCache.get().<Long, Group>getCache(Group.IDCACHE);
        if (!cache.containsKey(_id) && !Group.getGroupFromDB(Group.SQL_ID, _id)) {
            cache.put(_id, Group.NULL, 100, TimeUnit.SECONDS);
        }
        final Group ret = cache.get(_id);
        return ret.equals(Group.NULL) ? null : ret;
    }

    /**
     * Returns for given parameter _name the instance of class
     * {@link Group}.
     *
     * @param _name name to search in the cache
     * @return instance of class {@link Group}
     * @throws CacheReloadException on error
     */
    public static Group get(final String _name)
        throws CacheReloadException
    {
        final Cache<String, Group> cache = InfinispanCache.get().<String, Group>getCache(Group.IDCACHE);
        if (!cache.containsKey(_name) && !Group.getGroupFromDB(Group.SQL_NAME, _name)) {
            cache.put(_name, Group.NULL, 100, TimeUnit.SECONDS);
        }
        final Group ret = cache.get(_name);
        return ret.equals(Group.NULL) ? null : ret;
    }

    /**
     * Returns for given parameter _uuid the instance of class
     * {@link Group}.
     *
     * @param _uuid _uuid to search in the cache
     * @return instance of class {@link Group}
     * @throws CacheReloadException on error
     */
    public static Group get(final UUID _uuid)
        throws CacheReloadException
    {
        final Cache<UUID, Group> cache = InfinispanCache.get().<UUID, Group>getCache(Group.IDCACHE);
        if (!cache.containsKey(_uuid) && !Group.getGroupFromDB(Group.SQL_UUID, _uuid.toString())) {
            cache.put(_uuid, Group.NULL, 100, TimeUnit.SECONDS);
        }
        final Group ret = cache.get(_uuid);
        return ret.equals(Group.NULL) ? null : ret;
    }

    /**
     * Returns for given parameter _jaasKey the instance of class
     * {@link Group}. The parameter _jaasKey is the name of the group
     * used in the given JAAS system for the group.
     *
     * @param _jaasSystem   JAAS system for which the JAAS key is named
     * @param _jaasKey      key in the foreign JAAS system for which the group
     *                      is searched
     * @return instance of class {@link Group}, or null if group
     *         is not found
     * @throws EFapsException if group with JAAS key could not be fetched from
     *                        eFaps
     * @see #get(long)
     */
    public static Group getWithJAASKey(final JAASSystem _jaasSystem,
                                       final String _jaasKey)
        throws EFapsException
    {
        long groupId = 0;
        Connection con = null;
        try {
            con = Context.getConnection();

            PreparedStatement stmt = null;
            try {
                stmt = con.prepareStatement(Group.SQL_JAASKEY);
                stmt.setObject(1, _jaasKey);
                stmt.setObject(2, _jaasSystem.getId());
                final ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    groupId = rs.getLong(1);
                }
                rs.close();
            } catch (final SQLException e) {
                Group.LOG.error("search for group for JAAS system '" + _jaasSystem.getName() + "' "
                        + "with key '" + _jaasKey + "' is not possible", e);
                throw new EFapsException(Group.class, "getWithJAASKey.SQLException", e,
                                         _jaasSystem.getName(), _jaasKey);
            } finally {
                try {
                    stmt.close();
                    con.commit();
                } catch (final SQLException e) {
                    Group.LOG.error("Statement could not be closed", e);
                }
            }
        } finally {
            try {
                if (con != null && !con.isClosed()) {
                    con.close();
                }
            } catch (final SQLException e) {
                throw new CacheReloadException("Cannot read a type for an attribute.", e);
            }
        }
        return Group.get(groupId);
    }

    /**
     * @param _group Group to be cached
     */
    private static void cacheGroup(final Group _group)
    {
        final Cache<String, Group> nameCache = InfinispanCache.get().<String, Group>getIgnReCache(Group.NAMECACHE);
        nameCache.putIfAbsent(_group.getName(), _group);

        final Cache<Long, Group> idCache = InfinispanCache.get().<Long, Group>getIgnReCache(Group.IDCACHE);
        idCache.putIfAbsent(_group.getId(), _group);

        final Cache<UUID, Group> uuidCache = InfinispanCache.get().<UUID, Group>getIgnReCache(Group.UUIDCACHE);
        uuidCache.putIfAbsent(_group.getUUID(), _group);
    }

    /**
     * @param _sql      SQL Statment to be execuetd
     * @param _criteria filter criteria
     * @return true if successful
     * @throws CacheReloadException on error
     */
    private static boolean getGroupFromDB(final String _sql,
                                          final Object _criteria)
        throws CacheReloadException
    {
        boolean ret = false;
        Connection con = null;
        try {
            con = Context.getConnection();
            PreparedStatement stmt = null;
            try {
                stmt = con.prepareStatement(_sql);
                stmt.setObject(1, _criteria);
                final ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    final long id = rs.getLong(1);
                    final String uuid = rs.getString(2);
                    final String name = rs.getString(3).trim();
                    final boolean status = rs.getBoolean(4);
                    Group.LOG.debug("read group '{}' (id = {}, uuid = {})", name, id, uuid);
                    final Group group = new Group(id, uuid, name, status);
                    Group.cacheGroup(group);
                    ret = true;
                }
                rs.close();
            } finally {
                if (stmt != null) {
                    stmt.close();
                }
            }
            con.commit();
        } catch (final SQLException e) {
            throw new CacheReloadException("could not read Groups", e);
        } catch (final EFapsException e) {
            throw new CacheReloadException("could not read Groups", e);
        } finally {
            try {
                if (con != null && !con.isClosed()) {
                    con.close();
                }
            } catch (final SQLException e) {
                throw new CacheReloadException("Cannot read a type for an attribute.", e);
            }
        }
        return ret;
    }
}

redpajama_set_name: RedPajamaGithub


text:
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_Graphics3D_API;
using blink::WebConsoleMessage;
using blink::WebLocalFrame;
using blink::WebPluginContainer;
using blink::WebString;

namespace content {

PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PP_Instance instance)
    : PPB_Graphics3D_Shared(instance),
      bound_to_instance_(false),
      commit_pending_(false),
      has_alpha_(false),
      use_image_chromium_(
          !base::CommandLine::ForCurrentProcess()->HasSwitch(
              switches::kDisablePepper3DImageChromium) &&
          base::FeatureList::IsEnabled(features::kPepper3DImageChromium)) {}

PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() {
  // Unset the client before the command_buffer_ is destroyed, similar to how
  // WeakPtrFactory invalidates before it.
  if (command_buffer_)
    command_buffer_->SetGpuControlClient(nullptr);
}

// static
PP_Resource PPB_Graphics3D_Impl::CreateRaw(
    PP_Instance instance,
    PP_Resource share_context,
    const gpu::ContextCreationAttribs& attrib_helper,
    gpu::Capabilities* capabilities,
    const base::UnsafeSharedMemoryRegion** shared_state_region,
    gpu::CommandBufferId* command_buffer_id) {
  PPB_Graphics3D_API* share_api = nullptr;
  if (share_context) {
    EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
    if (enter.failed())
      return 0;
    share_api = enter.object();
  }
  scoped_refptr<PPB_Graphics3D_Impl> graphics_3d(
      new PPB_Graphics3D_Impl(instance));
  if (!graphics_3d->InitRaw(share_api, attrib_helper, capabilities,
                            shared_state_region, command_buffer_id))
    return 0;
  return graphics_3d->GetReference();
}

PP_Bool PPB_Graphics3D_Impl::SetGetBuffer(int32_t transfer_buffer_id) {
  GetCommandBuffer()->SetGetBuffer(transfer_buffer_id);
  return PP_TRUE;
}

scoped_refptr<gpu::Buffer> PPB_Graphics3D_Impl::CreateTransferBuffer(
    uint32_t size,
    int32_t* id) {
  return GetCommandBuffer()->CreateTransferBuffer(size, id);
}

PP_Bool PPB_Graphics3D_Impl::DestroyTransferBuffer(int32_t id) {
  GetCommandBuffer()->DestroyTransferBuffer(id);
  return PP_TRUE;
}

PP_Bool PPB_Graphics3D_Impl::Flush(int32_t put_offset) {
  GetCommandBuffer()->Flush(put_offset);
  return PP_TRUE;
}

gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForTokenInRange(
    int32_t start,
    int32_t end) {
  return GetCommandBuffer()->WaitForTokenInRange(start, end);
}

gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForGetOffsetInRange(
    uint32_t set_get_buffer_count,
    int32_t start,
    int32_t end) {
  return GetCommandBuffer()->WaitForGetOffsetInRange(set_get_buffer_count,
                                                     start, end);
}

void PPB_Graphics3D_Impl::EnsureWorkVisible() {
  command_buffer_->EnsureWorkVisible();
}

void PPB_Graphics3D_Impl::TakeFrontBuffer() {
  taken_front_buffer_ = GenerateMailbox();
  command_buffer_->TakeFrontBuffer(taken_front_buffer_);
}

void PPB_Graphics3D_Impl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
                                            const gpu::SyncToken& sync_token,
                                            bool is_lost) {
  command_buffer_->ReturnFrontBuffer(mailbox, sync_token, is_lost);
  mailboxes_to_reuse_.push_back(mailbox);
}

bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
  bound_to_instance_ = bind;
  return true;
}

bool PPB_Graphics3D_Impl::IsOpaque() { return !has_alpha_; }

void PPB_Graphics3D_Impl::ViewInitiatedPaint() {
  commit_pending_ = false;

  if (HasPendingSwap())
    SwapBuffersACK(PP_OK);
}

gpu::CommandBufferProxyImpl* PPB_Graphics3D_Impl::GetCommandBufferProxy() {
  DCHECK(command_buffer_);
  return command_buffer_.get();
}

gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() {
  return command_buffer_.get();
}

gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() {
  return command_buffer_.get();
}

int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token,
                                           const gfx::Size& size) {
  DCHECK(command_buffer_);
  if (taken_front_buffer_.IsZero()) {
    DLOG(ERROR) << "TakeFrontBuffer should be called before DoSwapBuffers";
    return PP_ERROR_FAILED;
  }

  if (bound_to_instance_) {
    // If we are bound to the instance, we need to ask the compositor
    // to commit our backing texture so that the graphics appears on the page.
    // When the backing texture will be committed we get notified via
    // ViewFlushedPaint().
    //
    // Don't need to check for NULL from GetPluginInstance since when we're
    // bound, we know our instance is valid.
    bool is_overlay_candidate = use_image_chromium_;
    // TODO(reveman): Get texture target from browser process.
    uint32_t target = GL_TEXTURE_2D;
#if defined(OS_MACOSX)
    if (use_image_chromium_)
      target = GL_TEXTURE_RECTANGLE_ARB;
#endif
    viz::TransferableResource resource = viz::TransferableResource::MakeGL(
        taken_front_buffer_, GL_LINEAR, target, sync_token, size,
        is_overlay_candidate);
    HostGlobals::Get()
        ->GetInstance(pp_instance())
        ->CommitTransferableResource(resource);
    commit_pending_ = true;
  } else {
    // Wait for the command to complete on the GPU to allow for throttling.
    command_buffer_->SignalSyncToken(
        sync_token, base::BindOnce(&PPB_Graphics3D_Impl::OnSwapBuffers,
                                   weak_ptr_factory_.GetWeakPtr()));
  }

  return PP_OK_COMPLETIONPENDING;
}

bool PPB_Graphics3D_Impl::InitRaw(
    PPB_Graphics3D_API* share_context,
    const gpu::ContextCreationAttribs& requested_attribs,
    gpu::Capabilities* capabilities,
    const base::UnsafeSharedMemoryRegion** shared_state_region,
    gpu::CommandBufferId* command_buffer_id) {
  PepperPluginInstanceImpl* plugin_instance =
      HostGlobals::Get()->GetInstance(pp_instance());
  if (!plugin_instance)
    return false;

  RenderFrame* render_frame = plugin_instance->GetRenderFrame();
  if (!render_frame)
    return false;

  const WebPreferences& prefs = render_frame->GetWebkitPreferences();

  // 3D access might be disabled.
  if (!prefs.pepper_3d_enabled)
    return false;

  // Force SW rendering for keyframe extraction to avoid pixel reads from VRAM.
  PluginInstanceThrottlerImpl* throttler = plugin_instance->throttler();
  if (throttler && throttler->needs_representative_keyframe())
    return false;

  RenderThreadImpl* render_thread = RenderThreadImpl::current();
  if (!render_thread)
    return false;
  if (render_thread->IsGpuCompositingDisabled())
    return false;

  scoped_refptr<gpu::GpuChannelHost> channel =
      render_thread->EstablishGpuChannelSync();
  if (!channel)
    return false;
  // 3D access might be blacklisted.
  if (channel->gpu_feature_info()
          .status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL] ==
      gpu::kGpuFeatureStatusBlacklisted) {
    return false;
  }

  has_alpha_ = requested_attribs.alpha_size > 0;

  gpu::ContextCreationAttribs attrib_helper = requested_attribs;
  attrib_helper.should_use_native_gmb_for_backbuffer = use_image_chromium_;
  attrib_helper.context_type = gpu::CONTEXT_TYPE_OPENGLES2;

  gpu::CommandBufferProxyImpl* share_buffer = nullptr;
  if (!plugin_instance->is_flash_plugin())
    UMA_HISTOGRAM_BOOLEAN("Pepper.Graphics3DHasShareGroup", !!share_context);
  if (share_context) {
    PPB_Graphics3D_Impl* share_graphics =
        static_cast<PPB_Graphics3D_Impl*>(share_context);
    share_buffer = share_graphics->GetCommandBufferProxy();
  }

  command_buffer_ = std::make_unique<gpu::CommandBufferProxyImpl>(
      std::move(channel), render_thread->GetGpuMemoryBufferManager(),
      kGpuStreamIdDefault, base::ThreadTaskRunnerHandle::Get());
  auto result = command_buffer_->Initialize(
      gpu::kNullSurfaceHandle, share_buffer, kGpuStreamPriorityDefault,
      attrib_helper, GURL::EmptyGURL());
  if (result != gpu::ContextResult::kSuccess)
    return false;

  command_buffer_->SetGpuControlClient(this);

  if (shared_state_region)
    *shared_state_region = &command_buffer_->GetSharedStateRegion();
  if (capabilities)
    *capabilities = command_buffer_->GetCapabilities();
  if (command_buffer_id)
    *command_buffer_id = command_buffer_->GetCommandBufferID();

  return true;
}

void PPB_Graphics3D_Impl::OnGpuControlErrorMessage(const char* message,
                                                   int32_t id) {
  if (!bound_to_instance_)
    return;
  WebPluginContainer* container =
      HostGlobals::Get()->GetInstance(pp_instance())->container();
  if (!container)
    return;
  WebLocalFrame* frame = container->GetDocument().GetFrame();
  if (!frame)
    return;
  WebConsoleMessage console_message = WebConsoleMessage(
      blink::mojom::ConsoleMessageLevel::kError, WebString::FromUTF8(message));
  frame->AddMessageToConsole(console_message);
}

void PPB_Graphics3D_Impl::OnGpuControlLostContext() {
#if DCHECK_IS_ON()
  // This should never occur more than once.
  DCHECK(!lost_context_);
  lost_context_ = true;
#endif

  // Don't need to check for null from GetPluginInstance since when we're
  // bound, we know our instance is valid.
  if (bound_to_instance_) {
    HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics(pp_instance(),
                                                                 0);
  }

  // Send context lost to plugin. This may have been caused by a PPAPI call, so
  // avoid re-entering.
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&PPB_Graphics3D_Impl::SendContextLost,
                                weak_ptr_factory_.GetWeakPtr()));
}

void PPB_Graphics3D_Impl::OnGpuControlLostContextMaybeReentrant() {
  // No internal state to update on lost context.
}

void PPB_Graphics3D_Impl::OnGpuControlSwapBuffersCompleted(
    const gpu::SwapBuffersCompleteParams& params) {}

void PPB_Graphics3D_Impl::OnGpuControlReturnData(
    base::span<const uint8_t> data) {
  NOTIMPLEMENTED();
}

void PPB_Graphics3D_Impl::OnSwapBuffers() {
  if (HasPendingSwap()) {
    // If we're off-screen, no need to trigger and wait for compositing.
    // Just send the swap-buffers ACK to the plugin immediately.
    commit_pending_ = false;
    SwapBuffersACK(PP_OK);
  }
}

void PPB_Graphics3D_Impl::SendContextLost() {
  // By the time we run this, the instance may have been deleted, or in the
  // process of being deleted. Even in the latter case, we don't want to send a
  // callback after DidDestroy.
  PepperPluginInstanceImpl* instance =
      HostGlobals::Get()->GetInstance(pp_instance());
  if (!instance || !instance->container())
    return;

  // This PPB_Graphics3D_Impl could be deleted during the call to
  // GetPluginInterface (which sends a sync message in some cases). We still
  // send the Graphics3DContextLost to the plugin; the instance may care about
  // that event even though this context has been destroyed.
  PP_Instance this_pp_instance = pp_instance();
  const PPP_Graphics3D* ppp_graphics_3d = static_cast<const PPP_Graphics3D*>(
      instance->module()->GetPluginInterface(PPP_GRAPHICS_3D_INTERFACE));
  // We have to check *again* that the instance exists, because it could have
  // been deleted during GetPluginInterface(). Even the PluginModule could be
  // deleted, but in that case, the instance should also be gone, so the
  // GetInstance check covers both cases.
  if (ppp_graphics_3d && HostGlobals::Get()->GetInstance(this_pp_instance))
    ppp_graphics_3d->Graphics3DContextLost(this_pp_instance);
}

gpu::Mailbox PPB_Graphics3D_Impl::GenerateMailbox() {
  if (!mailboxes_to_reuse_.empty()) {
    gpu::Mailbox mailbox = mailboxes_to_reuse_.back();
    mailboxes_to_reuse_.pop_back();
    return mailbox;
  }

  return gpu::Mailbox::Generate();
}

}  // namespace content


text:
package splain

import scala.collection.mutable

case class PluginSettings(pluginOpts: mutable.Map[String, String]) {

  import PluginSettings._

  def opt(key: String, default: String): String = pluginOpts.getOrElse(key, default)

  def enabled: Boolean = opt(Key.all, "true") == "true"

  def boolean(key: String): Boolean = enabled && opt(key, "true") == "true"

  def int(key: String): Option[Int] =
    if (enabled)
      pluginOpts.get(key).flatMap(a => scala.util.Try(a.toInt).toOption)
    else
      None

  // once read, changing pluginOpts will no longer be useful
  lazy val implicitDiverging: Boolean = boolean(PluginSettings.Key.implicitDiverging)

  lazy val implicitDivergingMaxDepth: Int = int(Key.implicitDivergingMaxDepth)
    .getOrElse(
      throw new UnsupportedOperationException(s"${Key.implicitDivergingMaxDepth} is not defined")
    )

}

object PluginSettings {

  object Key {

    val all = "all"
    val implicitDiverging = "Vimplicits-diverging"

    val implicitDivergingMaxDepth = "Vimplicits-diverging-max-depth"
  }

  val defaults = Map(
    Key.all -> "true",
    Key.implicitDiverging -> "false",
    Key.implicitDivergingMaxDepth -> "100"
  )
}


text:
%% feature-condition=BeanContextInitializer
\SetAPI{J-C}
\section{IoC Lifecycle}
\label{feature:IoCLifecycle}
\ClearAPI
\TODO


text:
{% extends "base.html" %}

{% block title %}{{ block.super }} – About – Advertising Information{% endblock title %}

{% block content %}

Advertising information

Download information

Download rate card

        {% if infopage.io_app %}
Download insertion order application</a
{% endif %}
        {% if infopage.credit_app %}
Download credit application</a
{% endif %}
        {% if infopage.contract %}
Download local contract</a
{% endif %}
        {% if infopage.back_cover_contract %}
Download back cover contract</a
{% endif %}

    {% if infopage.links %}

Additional advertising opportunities

        {% for link in infopage.links %}

{% if link.url %}{% endif %}{{ link }}{% if link.url %}{% endif %}

        {% endfor %}

    {% endif %}

Request information to be mailed

    <form method="POST" action="">

            {{ form.as_p }}

        <input type="submit" value="Send" />
    </form>

{% endblock content %}


text:
namespace Photogaleries.Services.Areas.HelpPage
{
    /// <summary>
    /// Indicates whether the sample is used for request or response
    /// </summary>
    public enum SampleDirection
    {
        Request = 0,
        Response
    }
}


text:
package org.jboss.weld.tests.event.async.context.security;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.concurrent.ExecutionException;

import jakarta.ejb.EJBAccessException;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.BeanArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.weld.test.util.Utils;
import org.jboss.weld.tests.category.Integration;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

/**
 * Testcase for WELD-1977
 *
 * @author Jozef Hartinger
 *
 */
@RunWith(Arquillian.class)
@Category(Integration.class)
public class SecurityContextPropagationTest {

    @Deployment
    public static Archive<?> getDeployment() {
        return ShrinkWrap.create(BeanArchive.class, Utils.getDeploymentNameAsHash(SecurityContextPropagationTest.class)).addPackage(SecurityContextPropagationTest.class.getPackage());
    }

    @Test
    public void testPositive(Student student) throws InterruptedException, ExecutionException {
        Spreadsheet spreadsheet = new Spreadsheet();
        assertEquals(spreadsheet, student.print(spreadsheet));
    }

    @Test
    public void testNegative(Stranger stranger) throws InterruptedException, ExecutionException {
        try {
            stranger.print(new Spreadsheet());
            fail();
        } catch (ExecutionException expected) {
            // CompletableFuture unwraps CompletionException automatically
            assertTrue(expected.getCause() instanceof EJBAccessException);
        }
    }
}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84.h
Label Definition File: CWE23_Relative_Path_Traversal.label.xml
Template File: sources-sink-84.tmpl.h
*/
/*
 * @description
 * CWE: 23 Relative Path Traversal
 * BadSource: environment Read input from an environment variable
 * GoodSource: Use a fixed file name
 * Sinks: w32CreateFile
 *    BadSink : Open the file named in data using CreateFile()
 * Flow Variant: 84 Data flow: data passed to class constructor and destructor by declaring the class object on the heap and deleting it after use
 *
 * */

#include "std_testcase.h"

#ifdef _WIN32
#define BASEPATH "c:\\temp\\"
#else
#include <wchar.h>
#define BASEPATH "/tmp/"
#endif

namespace CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84
{

#ifndef OMITBAD

class CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_bad
{
public:
    CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_bad(char * dataCopy);
    ~CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_bad();

private:
    char * data;
};

#endif /* OMITBAD */

#ifndef OMITGOOD

class CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_goodG2B
{
public:
    CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_goodG2B(char * dataCopy);
    ~CWE23_Relative_Path_Traversal__char_environment_w32CreateFile_84_goodG2B();

private:
    char * data;
};

#endif /* OMITGOOD */

}


text:
package org.apache.polygene.tutorials.composites.tutorial7;

import org.apache.polygene.api.mixin.Mixins;
import org.apache.polygene.api.sideeffect.SideEffects;

// START SNIPPET: solution

/**
 * This Composite interface declares transitively
 * all the Fragments of the HelloWorld composite.
 * <p>
 * It declares that the HelloWorldBehaviourSideEffect should be applied.
 * </p>
 */
@Mixins( { HelloWorldBehaviourMixin.class, HelloWorldStateMixin.class } )
@SideEffects( HelloWorldBehaviourSideEffect.class )
public interface HelloWorldComposite
    extends HelloWorld
{
}
// END SNIPPET: solution


text:
package at.vizu.s2n.exception

import at.vizu.s2n.types.symbol.Context

/**
 * Phil on 16.10.15.
 */
class TypeException(file: String, line: Int, message: String) extends RuntimeException(message) {
  def this(ctx: Context, message: String) = this(ctx.fileName, ctx.line, message)
  val formattedMessage = s"$file:$line: error: $message"

}


text:
const void* const kChromeNavigationDataUserDataKey =
    &kChromeNavigationDataUserDataKey;

ChromeNavigationData::ChromeNavigationData() {}

ChromeNavigationData::~ChromeNavigationData() {}

ChromeNavigationData* ChromeNavigationData::GetDataAndCreateIfNecessary(
    net::URLRequest* request) {
  if (!request)
    return nullptr;
  ChromeNavigationData* data = static_cast<ChromeNavigationData*>(
      request->GetUserData(kChromeNavigationDataUserDataKey));
  if (data)
    return data;
  data = new ChromeNavigationData();
  request->SetUserData(kChromeNavigationDataUserDataKey, data);
  return data;
}

std::unique_ptr<content::NavigationData> ChromeNavigationData::Clone() const {
  std::unique_ptr<ChromeNavigationData> copy(new ChromeNavigationData());
  if (data_reduction_proxy_data_)
    copy->SetDataReductionProxyData(data_reduction_proxy_data_->DeepCopy());
  return std::move(copy);
}


text:
html, body {
	height: 100%;
	width: 100%;
}

body {
	font-family: Arial, Helvetica, sans-serif;
	margin: 0;
	background: #7F7F7F;
}

#sliderContainer {
	position: absolute;
	top: 50%;
	left: 50%;
	border: 2px solid #ffffff;
	margin: -85px 0 0 -225px;
	padding: 10px;
	text-align: center;
	width: 500px;
	height: 170px;
}

#sliderContainer h1 {
	color: #ffffff;
}

#sliderContainer #colourCode {
	text-transform: uppercase;
}

#sliderContainer #slider_r .ui-slider-handle {
	background: #ff0000;
}

#sliderContainer #slider_g .ui-slider-handle {
	background: #00ff00;
}

#sliderContainer #slider_b .ui-slider-handle {
	background: #0000ff;
}

#sliderContainer .colourSlider {
	margin: 15px 10px;
}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE126_Buffer_Overread__CWE170_wchar_t_memcpy_15.c
Label Definition File: CWE126_Buffer_Overread__CWE170.label.xml
Template File: point-flaw-15.tmpl.c
*/
/*
 * @description
 * CWE: 126 Buffer Overread
 * Sinks: memcpy
 *    GoodSink: Copy a string using memcpy with explicit null termination
 *    BadSink : Copy a string using memcpy without explicit null termination
 * Flow Variant: 15 Control flow: switch(6)
 *
 * */

#include "std_testcase.h"

#include <wchar.h>

#ifndef OMITBAD

void CWE126_Buffer_Overread__CWE170_wchar_t_memcpy_15_bad()
{
    switch(6)
    {
    case 6:
    {
        wchar_t data[150], dest[100];
        /* Initialize data */
        wmemset(data, L'A', 149);
        data[149] = L'\0';
        memcpy(dest, data, 99*sizeof(wchar_t));
        /* FLAW: do not explicitly null terminate dest after the use of memcpy */
        printWLine(dest);
    }
    break;
    default:
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
        break;
    }
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* good1() changes the switch to switch(5) */
static void good1()
{
    switch(5)
    {
    case 6:
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
        break;
    default:
    {
        wchar_t data[150], dest[100];
        /* Initialize data */
        wmemset(data, L'A', 149);
        data[149] = L'\0';
        memcpy(dest, data, 99*sizeof(wchar_t));
        dest[99] = L'\0'; /* FIX: null terminate dest */
        printWLine(dest);
    }
    break;
    }
}

/* good2() reverses the blocks in the switch */
static void good2()
{
    switch(6)
    {
    case 6:
    {
        wchar_t data[150], dest[100];
        /* Initialize data */
        wmemset(data, L'A', 149);
        data[149] = L'\0';
        memcpy(dest, data, 99*sizeof(wchar_t));
        dest[99] = L'\0'; /* FIX: null terminate dest */
        printWLine(dest);
    }
    break;
    default:
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
        break;
    }
}

void CWE126_Buffer_Overread__CWE170_wchar_t_memcpy_15_good()
{
    good1();
    good2();
}

#endif /* OMITGOOD */

/* Below is the main(). It is only used when building this testcase on
   its own for testing or for building a binary to use in testing binary
   analysis tools. It is not used when compiling all the testcases as one
   application, which is how source code analysis tools are tested. */

#ifdef INCLUDEMAIN

int main(int argc, char * argv[])
{
    /* seed randomness */
    srand( (unsigned)time(NULL) );
#ifndef OMITGOOD
    printLine("Calling good()...");
    CWE126_Buffer_Overread__CWE170_wchar_t_memcpy_15_good();
    printLine("Finished good()");
#endif /* OMITGOOD */
#ifndef OMITBAD
    printLine("Calling bad()...");
    CWE126_Buffer_Overread__CWE170_wchar_t_memcpy_15_bad();
    printLine("Finished bad()");
#endif /* OMITBAD */
    return 0;
}

#endif


text:
require 'google/apis/core/base_service'
require 'google/apis/core/json_representation'
require 'google/apis/core/hashable'
require 'google/apis/errors'

module Google
  module Apis
    module MybusinessaccountmanagementV1
      # My Business Account Management API
      #
      # The My Business Account Management API provides an interface for managing
      #  access to a location on Google.
      #
      # @example
      #    require 'google/apis/mybusinessaccountmanagement_v1'
      #
      #    Mybusinessaccountmanagement = Google::Apis::MybusinessaccountmanagementV1 # Alias the module
      #    service = Mybusinessaccountmanagement::MyBusinessAccountManagementService.new
      #
      # @see https://developers.google.com/my-business/
      class MyBusinessAccountManagementService < Google::Apis::Core::BaseService
        # @return [String]
        #  API key. Your API key identifies your project and provides you with API access,
        #  quota, and reports. Required unless you provide an OAuth 2.0 token.
        attr_accessor :key

        # @return [String]
        #  Available to use for quota purposes for server-side applications. Can be any
        #  arbitrary string assigned to a user, but should not exceed 40 characters.
        attr_accessor :quota_user

        def initialize
          super('https://mybusinessaccountmanagement.googleapis.com/', '',
                client_name: 'google-apis-mybusinessaccountmanagement_v1',
                client_version: Google::Apis::MybusinessaccountmanagementV1::GEM_VERSION)
          @batch_path = 'batch'
        end

        # Creates an account with the specified name and type under the given parent. -
        # Personal accounts and Organizations cannot be created. - User Groups cannot be
        # created with a Personal account as primary owner. - Location Groups cannot be
        # created with a primary owner of a Personal account if the Personal account is
        # in an Organization. - Location Groups cannot own Location Groups.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Account] account_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Account] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Account]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def create_account(account_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/accounts', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Account::Representation
          command.request_object = account_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Account::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Account
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Gets the specified account. Returns `NOT_FOUND` if the account does not exist
        # or if the caller does not have access rights to it.
        # @param [String] name
        #   Required. The name of the account to fetch.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Account] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Account]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def get_account(name, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'v1/{+name}', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Account::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Account
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Lists all of the accounts for the authenticated user. This includes all
        # accounts that the user owns, as well as any accounts for which the user has
        # management rights.
        # @param [String] filter
        #   Optional. A filter constraining the accounts to return. The response includes
        #   only entries that match the filter. If `filter` is empty, then no constraints
        #   are applied and all accounts (paginated) are retrieved for the requested
        #   account. For example, a request with the filter `type=USER_GROUP` will only
        #   return user groups. The `type` field is the only supported filter.
        # @param [Fixnum] page_size
        #   Optional. How many accounts to fetch per page. The default and maximum is 20.
        # @param [String] page_token
        #   Optional. If specified, the next page of accounts is retrieved. The `pageToken`
        #   is returned when a call to `accounts.list` returns more results than can fit
        #   into the requested page size.
        # @param [String] parent_account
        #   Optional. The resource name of the account for which the list of directly
        #   accessible accounts is to be retrieved. This only makes sense for
        #   Organizations and User Groups. If empty, will return `ListAccounts` for the
        #   authenticated user. `accounts/`account_id``.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::ListAccountsResponse] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::ListAccountsResponse]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def list_accounts(filter: nil, page_size: nil, page_token: nil, parent_account: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'v1/accounts', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::ListAccountsResponse::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::ListAccountsResponse
          command.query['filter'] = filter unless filter.nil?
          command.query['pageSize'] = page_size unless page_size.nil?
          command.query['pageToken'] = page_token unless page_token.nil?
          command.query['parentAccount'] = parent_account unless parent_account.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Updates the specified business account. Personal accounts cannot be updated
        # using this method.
        # @param [String] name
        #   Immutable. The resource name, in the format `accounts/`account_id``.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Account] account_object
        # @param [String] update_mask
        #   Required. The specific fields that should be updated. The only editable field
        #   is `accountName`.
        # @param [Boolean] validate_only
        #   Optional. If true, the request is validated without actually updating the
        #   account.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Account] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Account]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def patch_account(name, account_object = nil, update_mask: nil, validate_only: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:patch, 'v1/{+name}', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Account::Representation
          command.request_object = account_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Account::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Account
          command.params['name'] = name unless name.nil?
          command.query['updateMask'] = update_mask unless update_mask.nil?
          command.query['validateOnly'] = validate_only unless validate_only.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Invites the specified user to become an administrator for the specified
        # account. The invitee must accept the invitation in order to be granted access
        # to the account. See AcceptInvitation to programmatically accept an invitation.
        # @param [String] parent
        #   Required. The resource name of the account this admin is created for. `
        #   accounts/`account_id``.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Admin] admin_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Admin] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Admin]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def create_account_admin(parent, admin_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/{+parent}/admins', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.request_object = admin_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Admin
          command.params['parent'] = parent unless parent.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Removes the specified admin from the specified account.
        # @param [String] name
        #   Required. The resource name of the admin to remove from the account. `accounts/
        #   `account_id`/admins/`admin_id``.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Empty] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Empty]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def delete_account_admin(name, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:delete, 'v1/{+name}', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Empty::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Empty
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Lists the admins for the specified account.
        # @param [String] parent
        #   Required. The name of the account from which to retrieve a list of admins. `
        #   accounts/`account_id`/admins`.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::ListAccountAdminsResponse] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::ListAccountAdminsResponse]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def list_account_admins(parent, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'v1/{+parent}/admins', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::ListAccountAdminsResponse::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::ListAccountAdminsResponse
          command.params['parent'] = parent unless parent.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Updates the Admin for the specified Account Admin.
        # @param [String] name
        #   Immutable. The resource name. For account admins, this is in the form: `
        #   accounts/`account_id`/admins/`admin_id`` For location admins, this is in the
        #   form: `locations/`location_id`/admins/`admin_id`` This field will be ignored
        #   if set during admin creation.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Admin] admin_object
        # @param [String] update_mask
        #   Required. The specific fields that should be updated. The only editable field
        #   is role.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Admin] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Admin]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def patch_account_admin(name, admin_object = nil, update_mask: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:patch, 'v1/{+name}', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.request_object = admin_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Admin
          command.params['name'] = name unless name.nil?
          command.query['updateMask'] = update_mask unless update_mask.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Accepts the specified invitation.
        # @param [String] name
        #   Required. The name of the invitation that is being accepted. `accounts/`
        #   account_id`/invitations/`invitation_id``
        # @param [Google::Apis::MybusinessaccountmanagementV1::AcceptInvitationRequest] accept_invitation_request_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Empty] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Empty]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def accept_invitation(name, accept_invitation_request_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/{+name}:accept', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::AcceptInvitationRequest::Representation
          command.request_object = accept_invitation_request_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Empty::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Empty
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Declines the specified invitation.
        # @param [String] name
        #   Required. The name of the account invitation that is being declined. `accounts/
        #   `account_id`/invitations/`invitation_id``
        # @param [Google::Apis::MybusinessaccountmanagementV1::DeclineInvitationRequest] decline_invitation_request_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Empty] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Empty]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def decline_invitation(name, decline_invitation_request_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/{+name}:decline', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::DeclineInvitationRequest::Representation
          command.request_object = decline_invitation_request_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Empty::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Empty
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Lists pending invitations for the specified account.
        # @param [String] parent
        #   Required. The name of the account from which the list of invitations is being
        #   retrieved. `accounts/`account_id`/invitations`
        # @param [String] filter
        #   Optional. Filtering the response is supported via the Invitation.target_type
        #   field.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::ListInvitationsResponse] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::ListInvitationsResponse]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def list_account_invitations(parent, filter: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'v1/{+parent}/invitations', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::ListInvitationsResponse::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::ListInvitationsResponse
          command.params['parent'] = parent unless parent.nil?
          command.query['filter'] = filter unless filter.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Moves a location from an account that the user owns to another account that
        # the same user administers. The user must be an owner of the account the
        # location is currently associated with and must also be at least a manager of
        # the destination account.
        # @param [String] name
        #   Required. The name of the location to transfer. `locations/`location_id``.
        # @param [Google::Apis::MybusinessaccountmanagementV1::TransferLocationRequest] transfer_location_request_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Empty] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Empty]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def transfer_location(name, transfer_location_request_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/{+name}:transfer', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::TransferLocationRequest::Representation
          command.request_object = transfer_location_request_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Empty::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Empty
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Invites the specified user to become an administrator for the specified
        # location. The invitee must accept the invitation in order to be granted access
        # to the location. See AcceptInvitation to programmatically accept an invitation.
        # @param [String] parent
        #   Required. The resource name of the location this admin is created for. `
        #   locations/`location_id`/admins`.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Admin] admin_object
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Admin] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Admin]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def create_location_admin(parent, admin_object = nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:post, 'v1/{+parent}/admins', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.request_object = admin_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Admin
          command.params['parent'] = parent unless parent.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Removes the specified admin as a manager of the specified location.
        # @param [String] name
        #   Required. The resource name of the admin to remove from the location.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Empty] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Empty]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def delete_location_admin(name, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:delete, 'v1/{+name}', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Empty::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Empty
          command.params['name'] = name unless name.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Lists all of the admins for the specified location.
        # @param [String] parent
        #   Required. The name of the location to list admins of. `locations/`location_id`/
        #   admins`.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::ListLocationAdminsResponse] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::ListLocationAdminsResponse]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def list_location_admins(parent, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'v1/{+parent}/admins', options)
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::ListLocationAdminsResponse::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::ListLocationAdminsResponse
          command.params['parent'] = parent unless parent.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        # Updates the Admin for the specified location. Only the AdminRole of the Admin
        # can be updated.
        # @param [String] name
        #   Immutable. The resource name. For account admins, this is in the form: `
        #   accounts/`account_id`/admins/`admin_id`` For location admins, this is in the
        #   form: `locations/`location_id`/admins/`admin_id`` This field will be ignored
        #   if set during admin creation.
        # @param [Google::Apis::MybusinessaccountmanagementV1::Admin] admin_object
        # @param [String] update_mask
        #   Required. The specific fields that should be updated. The only editable field
        #   is role.
        # @param [String] fields
        #   Selector specifying which fields to include in a partial response.
        # @param [String] quota_user
        #   Available to use for quota purposes for server-side applications. Can be any
        #   arbitrary string assigned to a user, but should not exceed 40 characters.
        # @param [Google::Apis::RequestOptions] options
        #   Request-specific options
        #
        # @yield [result, err] Result & error if block supplied
        # @yieldparam result [Google::Apis::MybusinessaccountmanagementV1::Admin] parsed result object
        # @yieldparam err [StandardError] error object if request failed
        #
        # @return [Google::Apis::MybusinessaccountmanagementV1::Admin]
        #
        # @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried
        # @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification
        # @raise [Google::Apis::AuthorizationError] Authorization is required
        def patch_location_admin(name, admin_object = nil, update_mask: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:patch, 'v1/{+name}', options)
          command.request_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.request_object = admin_object
          command.response_representation = Google::Apis::MybusinessaccountmanagementV1::Admin::Representation
          command.response_class = Google::Apis::MybusinessaccountmanagementV1::Admin
          command.params['name'] = name unless name.nil?
          command.query['updateMask'] = update_mask unless update_mask.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end

        protected

        def apply_command_defaults(command)
          command.query['key'] = key unless key.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
        end
      end
    end
  end
end


text:
Simple cross platform plugin read a non-setoff card from shared code.
Ported from Xamarin.Mobile to a cross platform API.

###Setup
* Available on NuGet: https://www.nuget.org/packages/CrossCardReader/ [![NuGet](https://img.shields.io/nuget/v/CrossCardReader.svg?label=NuGet)](https://www.nuget.org/packages/CrossCardReader/)
* Install into your PCL project and Client projects.
* Please see the additional setup for each platforms permissions.

**Platform Support**

|Platform|Supported|Version|
| ------------------- | :-----------: | :------------------: |
|Xamarin.iOS|Yes|iOS 8+|
|Xamarin.iOS Unified|Yes|iOS 8+|
|Xamarin.Android|Yes|API 22+|

###API Usage
Call CrossCardReader.Current from any project or PCL to gain access to APIs.
Before taking photos or videos you should check to see if a camera exists and if photos and videos are supported on the device.

###Usage
Via a Xamarin.Forms project with a Button and Image to take a photo:

```csharp
takePhoto.Clicked += async (sender, args) =>
{
    await CrossCardReader.Current.Initialize("API_KEY");

    var supportedProducts = new Products();
    supportedProducts.Add("55123804");
    supportedProducts.Add("40276602");

    var card = await CrossCardReader.CrossCardReader.Current.RecognizeCardAsync(supportedProducts);
};
```

###Important Permission Information
Please read these as they must be implemented for all platforms.

###Android
The CAMERA permission is required.

By adding these permissions Google Play will automatically filter out devices without specific hardward. You can get around this by adding the following to your AssemblyInfo.cs file in your Android project:
[assembly: UsesFeature("android.hardware.camera", Required = false)]
[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]

###iOS
Your app is required to have NSPhotoLibraryUsageDescription  key in your Info.plist in order to access the device's camera. The string that you provide for each of these keys will be displayed to the user when they are prompted to provide permission to access these device features. You can read me here: https://blog.xamarin.com/new-ios-10-privacy-permission-settings/
Such as:
<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos.</string>

###Special Thanks

All of the [libraries and projects](OpenSource.md) that made this plugin possible.

Thanks!

The MIT License (MIT)

Copyright (c) 2016 Alset & Tristan Martinez

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


text:
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.maintenance;

import com.yahoo.config.provision.Deployer;
import com.yahoo.config.provision.Deployment;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TransientException;
import com.yahoo.jdisc.Metric;
import com.yahoo.transaction.Mutex;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.NodeMutex;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.Allocation;
import com.yahoo.vespa.hosted.provision.node.History;
import com.yahoo.vespa.orchestrator.ApplicationIdNotFoundException;
import com.yahoo.vespa.orchestrator.status.ApplicationInstanceStatus;
import com.yahoo.yolean.Exceptions;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * Maintains information in the node repo about when this node last responded to ping
 * and fails nodes which have not responded within the given time limit.
 *
 * @author bratseth
 * @author mpolden
 */
public class NodeFailer extends NodeRepositoryMaintainer {

    private static final Logger log = Logger.getLogger(NodeFailer.class.getName());

    /** Metric for number of hosts that we want to fail, but cannot due to throttling */
    static final String throttledHostFailuresMetric = "throttledHostFailures";

    /** Metric for number of nodes that we want to fail, but cannot due to throttling */
    static final String throttledNodeFailuresMetric = "throttledNodeFailures";

    /** Metric that indicates whether throttling is active where 1 means active and 0 means inactive */
    static final String throttlingActiveMetric = "nodeFailThrottling";

    private final Deployer deployer;
    private final Duration downTimeLimit;
    private final Duration suspendedDownTimeLimit;
    private final ThrottlePolicy throttlePolicy;
    private final Metric metric;

    public NodeFailer(Deployer deployer, NodeRepository nodeRepository,
                      Duration downTimeLimit, Duration interval, ThrottlePolicy throttlePolicy, Metric metric) {
        // check ping status every interval, but at least twice as often as the down time limit
        super(nodeRepository, min(downTimeLimit.dividedBy(2), interval), metric);
        this.deployer = deployer;
        this.downTimeLimit = downTimeLimit;
        this.suspendedDownTimeLimit = downTimeLimit.multipliedBy(4); // Allow more downtime when a node is suspended
        this.throttlePolicy = throttlePolicy;
        this.metric = metric;
    }

    @Override
    protected double maintain() {
        if ( ! nodeRepository().nodes().isWorking()) return 0.0;

        int attempts = 0;
        int failures = 0;
        int throttledHostFailures = 0;
        int throttledNodeFailures = 0;

        for (FailingNode failing : findActiveFailingNodes()) {
            attempts++;
            if (!failAllowedFor(failing.node().type())) continue;

            if (throttle(failing.node())) {
                failures++;
                if (failing.node().type().isHost())
                    throttledHostFailures++;
                else
                    throttledNodeFailures++;
                continue;
            }
            failActive(failing);
        }

        int throttlingActive = Math.min(1, throttledHostFailures + throttledNodeFailures);
        metric.set(throttlingActiveMetric, throttlingActive, null);
        metric.set(throttledHostFailuresMetric, throttledHostFailures, null);
        metric.set(throttledNodeFailuresMetric, throttledNodeFailures, null);
        return asSuccessFactor(attempts, failures);
    }

    private Collection<FailingNode> findActiveFailingNodes() {
        Set<FailingNode> failingNodes = new HashSet<>();
        NodeList activeNodes = nodeRepository().nodes().list(Node.State.active);

        for (Node host : activeNodes.hosts().failing())
            failingNodes.add(new FailingNode(host, "Host should be failed and have no tenant nodes"));

        for (Node node : activeNodes) {
            Instant graceTimeStart = clock().instant().minus(nodeRepository().nodes().suspended(node) ? suspendedDownTimeLimit : downTimeLimit);
            if (node.isDown() && node.history().hasEventBefore(History.Event.Type.down, graceTimeStart) && !applicationSuspended(node)) {
                // Allow a grace period after node re-activation
                if (!node.history().hasEventAfter(History.Event.Type.activated, graceTimeStart))
                    failingNodes.add(new FailingNode(node, "Node has been down longer than " + downTimeLimit));
            }
        }

        for (Node node : activeNodes) {
            if (allSuspended(node, activeNodes)) {
                Node host = node.parentHostname().flatMap(activeNodes::node).orElse(node);
                if (host.type().isHost()) {
                    List<String> failureReports = reasonsToFailHost(host);
                    if ( ! failureReports.isEmpty()) {
                        failingNodes.add(new FailingNode(node, host.equals(node) ?
                                                               "Host has failure reports: " + failureReports :
                                                               "Parent " + host + " has failure reports: " + failureReports));
                    }
                }
            }
        }

        return failingNodes;
    }

    public static List<String> reasonsToFailHost(Node host) {
        return host.reports().getReports().stream()
                .filter(report -> report.getType().hostShouldBeFailed())
                // The generated string is built from the report's ID, created time, and description only.
                .map(report -> report.getReportId() + " reported " + report.getCreatedTime() + ": " + report.getDescription())
                .collect(Collectors.toList());
    }

    /** Returns whether node has any kind of hardware issue */
    static boolean hasHardwareIssue(Node node, NodeList allNodes) {
        Node host = node.parentHostname().flatMap(allNodes::node).orElse(node);
        return reasonsToFailHost(host).size() > 0;
    }

    private boolean applicationSuspended(Node node) {
        try {
            return nodeRepository().orchestrator().getApplicationInstanceStatus(node.allocation().get().owner())
                   == ApplicationInstanceStatus.ALLOWED_TO_BE_DOWN;
        } catch (ApplicationIdNotFoundException e) {
            // Treat it as not suspended and allow to fail the node anyway
            return false;
        }
    }

    /** Is the node and all active children suspended? */
    private boolean allSuspended(Node node, NodeList activeNodes) {
        if (!nodeRepository().nodes().suspended(node)) return false;
        if (node.parentHostname().isPresent()) return true; // optimization
        return activeNodes.childrenOf(node.hostname()).stream().allMatch(nodeRepository().nodes()::suspended);
    }

    /**
     * We can attempt to fail any number of *tenant* and *host* nodes because the operation will not be effected
     * unless the node is replaced.
     * We can also attempt to fail a single proxy(host) as there should be enough redundancy to handle that.
     * But we refuse to fail out config(host)/controller(host)
     */
    private boolean failAllowedFor(NodeType nodeType) {
        switch (nodeType) {
            case tenant:
            case host:
                return true;
            case proxy:
            case proxyhost:
                return nodeRepository().nodes().list(Node.State.failed).nodeType(nodeType).isEmpty();
            default:
                return false;
        }
    }

    /**
     * Called when a node should be moved to the failed state: Do that if it seems safe,
     * which is when the node repo has available capacity to replace the node (and all its tenant nodes if host).
     * Otherwise not replacing the node ensures (by Orchestrator check) that no further action will be taken.
     *
     * @return whether node was successfully failed
     */
    private boolean failActive(FailingNode failing) {
        Optional<Deployment> deployment =
            deployer.deployFromLocalActive(failing.node().allocation().get().owner(), Duration.ofMinutes(30));
        if (deployment.isEmpty()) return false;

        // If the active node that we are trying to fail is of type host, we need to successfully fail all
        // the children nodes running on it before we fail the host.  Failing a child node in a dynamically
        // provisioned zone may require provisioning new hosts that require the host application lock to be held,
        // so we must release ours before failing the children.
        List<FailingNode> activeChildrenToFail = new ArrayList<>();
        try (NodeMutex lock = nodeRepository().nodes().lockAndGetRequired(failing.node())) {
            // Now that we have gotten the node object under the proper lock, sanity-check it still makes sense to fail
            if (!Objects.equals(failing.node().allocation().map(Allocation::owner), lock.node().allocation().map(Allocation::owner)))
                return false;
            if (lock.node().state() == Node.State.failed)
                return true;
            if (!Objects.equals(failing.node().state(), lock.node().state()))
                return false;
            failing = new FailingNode(lock.node(), failing.reason);

            String reasonForChildFailure = "Failing due to parent host " + failing.node().hostname() + " failure: " + failing.reason();
            for (Node failingTenantNode : nodeRepository().nodes().list().childrenOf(failing.node())) {
                if (failingTenantNode.state() == Node.State.active) {
                    activeChildrenToFail.add(new FailingNode(failingTenantNode, reasonForChildFailure));
                } else if (failingTenantNode.state() != Node.State.failed) {
                    nodeRepository().nodes().fail(failingTenantNode.hostname(), Agent.NodeFailer, reasonForChildFailure);
                }
            }

            if (activeChildrenToFail.isEmpty()) {
                wantToFail(failing.node(), true, lock);
                try {
                    deployment.get().activate();
                    return true;
                } catch (TransientException e) {
                    log.log(Level.INFO, "Failed to redeploy " + failing.node().allocation().get().owner() +
                                        " with a transient error, will be retried by application maintainer: " +
                                        Exceptions.toMessageString(e));
                    return true;
                } catch (RuntimeException e) {
                    // Reset want to fail: We'll retry failing unless it heals in the meantime
                    nodeRepository().nodes().node(failing.node().hostname())
                                    .ifPresent(n -> wantToFail(n, false, lock));
                    log.log(Level.WARNING, "Could not fail " + failing.node() + " for " + failing.node().allocation().get().owner() +
                                           " for " + failing.reason() + ": " + Exceptions.toMessageString(e));
                    return false;
                }
            }
        }

        // In a dynamically provisioned zone the failing of the first child may require a new host to be provisioned,
        // so failActive() may take a long time to complete, but the remaining children should be fast.
        activeChildrenToFail.forEach(this::failActive);

        return false;
    }

    private void wantToFail(Node node, boolean wantToFail, Mutex lock) {
        if (!node.status().wantToFail())
            nodeRepository().nodes().write(node.withWantToFail(wantToFail, Agent.NodeFailer, clock().instant()), lock);
    }

    /** Returns true if node failing should be throttled */
    private boolean throttle(Node node) {
        if (throttlePolicy == ThrottlePolicy.disabled) return false;
        Instant startOfThrottleWindow = clock().instant().minus(throttlePolicy.throttleWindow);
        NodeList allNodes = nodeRepository().nodes().list();
        NodeList recentlyFailedNodes = allNodes
                .matching(n -> n.status().wantToFail() ||
                               (n.state() == Node.State.failed &&
                                n.history().hasEventAfter(History.Event.Type.failed, startOfThrottleWindow)));

        // Allow failing any node within policy
        if (recentlyFailedNodes.size() < throttlePolicy.allowedToFailOf(allNodes.size())) return false;

        // Always allow failing a minimum number of hosts
        if (node.parentHostname().isEmpty()) {
            Set<String> parentsOfRecentlyFailedNodes = recentlyFailedNodes.stream()
                                                                          .map(n -> n.parentHostname().orElse(n.hostname()))
                                                                          .collect(Collectors.toSet());
            long potentiallyFailed = parentsOfRecentlyFailedNodes.contains(node.hostname()) ?
                                     parentsOfRecentlyFailedNodes.size() :
                                     parentsOfRecentlyFailedNodes.size() + 1;
            if (potentiallyFailed <= throttlePolicy.minimumAllowedToFail) return false;
        }

        // Always allow failing children of a failed host
        if (recentlyFailedNodes.parentOf(node).isPresent()) return false;

        log.info(String.format("Want to fail node %s, but throttling is in effect: %s", node.hostname(),
                               throttlePolicy.toHumanReadableString(allNodes.size())));

        return true;
    }

    public enum ThrottlePolicy {

        hosted(Duration.ofDays(1), 0.03, 2),
        disabled(Duration.ZERO, 0, 0);

        private final Duration throttleWindow;
        private final double fractionAllowedToFail;
        private final int minimumAllowedToFail;

        ThrottlePolicy(Duration throttleWindow, double fractionAllowedToFail, int minimumAllowedToFail) {
            this.throttleWindow = throttleWindow;
            this.fractionAllowedToFail = fractionAllowedToFail;
            this.minimumAllowedToFail = minimumAllowedToFail;
        }

        public int allowedToFailOf(int totalNodes) {
            return (int) Math.max(totalNodes * fractionAllowedToFail, minimumAllowedToFail);
        }

        public String toHumanReadableString(int totalNodes) {
            return String.format("Max %.0f%% (%d) or %d nodes can fail over a period of %s", fractionAllowedToFail*100,
                                 allowedToFailOf(totalNodes),
                                 minimumAllowedToFail, throttleWindow);
        }

    }

    private record FailingNode(Node node, String reason) { }

}


text:
import { APITypes } from '@oneblink/types'

describe('cors display', () => {
  afterEach(() => {
    jest.resetModules()
    jest.clearAllMocks()
  })

  const CWD = 'current working directory'
  const CORS: APITypes.APIEnvironmentCorsConfiguration = {
    origins: ['http://test'],
    headers: ['Accept', 'Content-Type'],
    exposedHeaders: ['Accept', 'Content-Type'],
  }

  beforeEach(() => {
    jest.mock('api/cors/read', () => {
      return () => Promise.resolve(CORS)
    })
    jest.mock('api/cors/validate', () => {
      return () => Promise.resolve(CORS)
    })
  })

  test('Should call read() with correct input', async () => {
    expect.assertions(1)
    jest.mock('api/cors/read', () => {
      return async (cwd: string) => {
        expect(cwd).toBe(CWD)
        return CORS
      }
    })

    const { default: display } = await import('../../../src/api/cors/display')
    return display(console, CWD)
  })

  test('Should not log or validate if read() does not return cors', async () => {
    expect.assertions(1)
    jest.mock('api/cors/read', () => {
      return async () => {
        return
      }
    })
    jest.mock('api/cors/validate', () => {
      return async () => {
        fail('Should not validate')
        return CORS
      }
    })
    const spy = jest.spyOn(console, 'log')

    const { default: display } = await import('../../../src/api/cors/display')
    await display(console, CWD)

    expect(spy).not.toHaveBeenCalled()
  })

  test('Should call validate() with correct input', async () => {
    jest.mock('api/cors/validate', () => {
      return async (cors: APITypes.APIEnvironmentCorsConfiguration) => {
        expect(cors).toEqual(CORS)
        return cors
      }
    })

    const { default: display } = await import('../../../src/api/cors/display')
    return display(console, CWD)
  })

  test('Should not log the cors and reject if no routes are found', async () => {
    jest.mock('api/cors/validate', () => {
      return async () => {
        throw new Error('test error message')
      }
    })

    const spy = jest.spyOn(console, 'log')

    const { default: display } = await import('../../../src/api/cors/display')
    const promise = display(console, CWD)

    await expect(promise).rejects.toHaveProperty(
      'message',
      'test error message',
    )

    expect(spy).not.toHaveBeenCalled()
  })

  test('Should log the cors', async () => {
    const spy = jest.spyOn(console, 'log')

    const { default: display } = await import('../../../src/api/cors/display')
    await display(console, CWD)

    expect(spy).toHaveBeenCalled()
  })
})


text:
Attributions
======

- Evil Icons (ei-pencil used in temp icon)
- node-webkit
- animate.css
- wow.js